📄 commandselect.java
字号:
/* =============================================================
* SmallSQL : a free Java DBMS library for the Java(tm) platform
* =============================================================
*
* (C) Copyright 2004-2006, by Volker Berlin.
*
* Project Info: http://www.smallsql.de/
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ---------------
* CommandSelect.java
* ---------------
* Author: Volker Berlin
*
*/
package smallsql.database;
import java.sql.*;
class CommandSelect extends Command{
private DataSources from; // List of TableResult
private Expression where;
RowSource join;
private Expressions groupBy;
private Expression having;
private Expressions orderBy;
private boolean isAggregateFunction;
private int maxRows = -1;
/** is set if the keyword DISTINCT is used */
private boolean isDistinct;
CommandSelect(Logger log){
super(log);
}
CommandSelect(Logger log, Expressions columnExpressions){
super(log, columnExpressions);
}
boolean compile(SSConnection con) throws Exception{
boolean needCompile = false;
if(from != null){
for(int i=0; i<from.size(); i++){
DataSource fromEntry = from.get(i);
needCompile |= fromEntry.init( con );
}
}
if(join == null){
join = new NoFromResult();
from = new DataSources();
needCompile = true;
}
if(!needCompile) return false;
for(int i=0; i<columnExpressions.size(); i++){
Expression col = columnExpressions.get(i);
if(col.getAlias() == null){
// f黵 Ausdr點ke automatische Namen vergeben
col.setAlias("col" + (i+1));
}
if(col.getType() != Expression.NAME){
compileLinkExpressionParams(col);
continue;
}
ExpressionName expr = (ExpressionName)col;
if("*".equals( expr.getName() )){
String tableAlias = expr.getTableAlias();
if(tableAlias != null){
// Syntax: tableAlias.*
int t=0;
for(; t<from.size(); t++){
DataSource fromEntry = from.get(t);
if(tableAlias.equalsIgnoreCase( fromEntry.getAlias() )){
TableView table = fromEntry.getTableView();
columnExpressions.remove(i);
i = compileAdd_All_Table_Columns( fromEntry, table, i ) - 1;
break;
}
}
if(t==from.size()) throw Utils.createSQLException( "The column prefix '" + tableAlias + "' does not match with a table name or alias name used in this query" );
}else{
// Syntax *
columnExpressions.remove(i);
for(int t=0; t<from.size(); t++){
DataSource fromEntry = from.get(t);
TableView table = fromEntry.getTableView();
i = compileAdd_All_Table_Columns( fromEntry, table, i );
}
i--;
}
}else{
// not a * Syntax
compileLinkExpressionName( expr );
}
}
if(where != null) compileLinkExpression( where );
if(having != null) compileLinkExpression( having );
if(orderBy != null) {
for(int i=0; i<orderBy.size(); i++){
compileLinkExpression( orderBy.get(i));
}
}
if(groupBy != null){
for(int i=0; i<groupBy.size(); i++){
compileLinkExpression( groupBy.get(i) );
}
}
if(join instanceof Join){
compileJoin( (Join)join );
}
if(where != null){
join = new Where( join, where );
}
if(isGroupResult()) {
join = new GroupResult( this, join, groupBy, having, orderBy);
if(having != null){
join = new Where( join, having );
}
}
if(isDistinct){
join = new Distinct( join, columnExpressions );
}
if(orderBy != null){
join = new SortedResult( join, orderBy );
}
return true;
}
/**
* If this ResultSet is use any type of grouping. This means that GroupResult need create and that
* the ResultSet is not updatable.
*/
final boolean isGroupResult(){
return groupBy != null || having != null || isAggregateFunction;
}
/**
* Set the link between the Named Expression and the Table object
* in the condition.
* If there are cascade Joins then follow the tree with a recursion.
*/
private void compileJoin( Join singleJoin ) throws Exception{
if(singleJoin.condition != null) compileLinkExpressionParams( singleJoin.condition );
if(singleJoin.left instanceof Join){
compileJoin( (Join)singleJoin.left );
}
if(singleJoin.right instanceof Join){
compileJoin( (Join)singleJoin.right );
}
}
private void compileLinkExpression( Expression expr) throws Exception{
if(expr.getType() == Expression.NAME)
compileLinkExpressionName( (ExpressionName)expr);
else compileLinkExpressionParams( expr );
}
/**
* Set the connection (link) of a named Expression to the table and the column index.
* This means a column name in the SQL statement is link to it table source.
*/
private void compileLinkExpressionName( ExpressionName expr ) throws Exception{
String tableAlias = expr.getTableAlias();
if(tableAlias != null){
int t=0;
for(; t<from.size(); t++){
DataSource fromEntry = from.get(t);
if(tableAlias.equalsIgnoreCase( fromEntry.getAlias() )){
TableView table = fromEntry.getTableView();
int colIdx = table.findColumnIdx( expr.getName() );
if(colIdx>=0){
// Column was find and now we set the DataSouce, column index and TableView.
expr.setFrom( fromEntry, colIdx, table );
break;
}else
throw Utils.createSQLException("Invalid column name '" + expr.getName() + "'.");
}
}
if(t==from.size()) throw Utils.createSQLException( "The column prefix '" + tableAlias + "' does not match with a table name or alias name used in this query" );
}else{
// column name without table name
int t=0;
for(; t<from.size(); t++){
DataSource fromEntry = from.get(t);
TableView table = fromEntry.getTableView();
int colIdx = table.findColumnIdx( expr.getName() );
if(colIdx>=0){
// Column was find and now we set the DataSouce, column index and TableView.
expr.setFrom( fromEntry, colIdx, table );
break;
}
}
if(t>=from.size()){
throw Utils.createSQLException("Invalid column name '" + expr.getName() + "'.");
}
}
compileLinkExpressionParams(expr);
}
private void compileLinkExpressionParams(Expression expr) throws Exception{
// check sub Expression (parameters)
Expression[] expParams = expr.getParams();
isAggregateFunction = isAggregateFunction || expr.getType() >= Expression.GROUP_BEGIN;
if(expParams != null){
for(int k=0; k<expParams.length; k++){
Expression param = expParams[k];
int paramType = param.getType();
isAggregateFunction = isAggregateFunction || paramType >= Expression.GROUP_BEGIN;
if(paramType == Expression.NAME)
compileLinkExpressionName( (ExpressionName)param );
else compileLinkExpressionParams( param );
}
}
expr.optimize();
}
private final int compileAdd_All_Table_Columns( DataSource fromEntry, TableView table, int position){
for(int k=0; k<table.columns.size(); k++){
ExpressionName expr = new ExpressionName( table.columns.get(k).getName() );
expr.setFrom( fromEntry, k, table );
columnExpressions.add( position++, expr );
}
return position;
}
/**
* The main method to execute this Command and create a ResultSet.
*/
void executeImpl(SSConnection con, SSStatement st) throws Exception{
compile(con);
if((st.rsType == ResultSet.TYPE_SCROLL_INSENSITIVE || st.rsType == ResultSet.TYPE_SCROLL_SENSITIVE) &&
!join.isScrollable()){
join = new Scrollable(join);
}
join.execute();
rs = new SSResultSet( st, this );
}
/**
* Is used from ResultSet.beforeFirst().
*
*/
void beforeFirst() throws Exception{
join.beforeFirst();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -