001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.OptimizerFactoryImpl
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.compile;
023:
024: import org.apache.derby.iapi.sql.compile.CostEstimate;
025: import org.apache.derby.iapi.sql.compile.JoinStrategy;
026: import org.apache.derby.iapi.sql.compile.OptimizableList;
027: import org.apache.derby.iapi.sql.compile.OptimizablePredicateList;
028: import org.apache.derby.iapi.sql.compile.Optimizer;
029: import org.apache.derby.iapi.sql.compile.OptimizerFactory;
030: import org.apache.derby.iapi.sql.compile.RequiredRowOrdering;
031:
032: import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
033:
034: import org.apache.derby.iapi.store.access.TransactionController;
035:
036: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
037:
038: import org.apache.derby.iapi.services.monitor.ModuleControl;
039: import org.apache.derby.iapi.services.context.ContextManager;
040: import org.apache.derby.iapi.services.property.PropertyUtil;
041:
042: import org.apache.derby.iapi.services.sanity.SanityManager;
043:
044: import org.apache.derby.iapi.error.StandardException;
045:
046: import org.apache.derby.iapi.reference.Property;
047:
048: import java.util.Properties;
049:
050: /**
051: This is simply the factory for creating an optimizer.
052: */
053:
054: public class OptimizerFactoryImpl implements ModuleControl,
055: OptimizerFactory {
056:
057: protected String optimizerId = null;
058: protected boolean ruleBasedOptimization = false;
059: protected boolean noTimeout = false;
060: protected boolean useStatistics = true;
061: protected int maxMemoryPerTable = 1048576;
062:
063: /*
064: ** The fact that we have one set of join strategies for use by all
065: ** optimizers means that the JoinStrategy[] must be immutable, and
066: ** also each JoinStrategy must be immutable.
067: */
068: protected JoinStrategy[] joinStrategySet;
069:
070: //
071: // ModuleControl interface
072: //
073:
074: public void boot(boolean create, Properties startParams)
075: throws StandardException {
076:
077: /*
078: ** This property determines whether to use rule-based or cost-based
079: ** optimization. It is used mainly for testing - there are many tests
080: ** that assume rule-based optimization. The default is cost-based
081: ** optimization.
082: */
083: ruleBasedOptimization = Boolean
084: .valueOf(
085: PropertyUtil
086: .getSystemProperty(Optimizer.RULE_BASED_OPTIMIZATION))
087: .booleanValue();
088:
089: /*
090: ** This property determines whether the optimizer should ever stop
091: ** optimizing a query because it has spent too long in optimization.
092: ** The default is that it will.
093: */
094: noTimeout = Boolean.valueOf(
095: PropertyUtil.getSystemProperty(Optimizer.NO_TIMEOUT))
096: .booleanValue();
097:
098: /*
099: ** This property determines the maximum size of memory (in KB)
100: ** the optimizer can use for each table. If an access path takes
101: ** memory larger than that size for a table, the access path is skipped.
102: ** Default is 1024 (KB).
103: */
104: String maxMemValue = PropertyUtil
105: .getSystemProperty(Optimizer.MAX_MEMORY_PER_TABLE);
106: if (maxMemValue != null) {
107: int intValue = Integer.parseInt(maxMemValue);
108: if (intValue >= 0)
109: maxMemoryPerTable = intValue * 1024;
110: }
111:
112: String us = PropertyUtil
113: .getSystemProperty(Optimizer.USE_STATISTICS);
114: if (us != null)
115: useStatistics = (Boolean.valueOf(us)).booleanValue();
116:
117: /* Allocation of joinStrategySet deferred til
118: * getOptimizer(), even though we only need 1
119: * array for this factory. We defer allocation
120: * to improve boot time on small devices.
121: */
122: }
123:
124: public void stop() {
125: }
126:
127: //
128: // OptimizerFactory interface
129: //
130:
131: /**
132: * @see OptimizerFactory#getOptimizer
133: *
134: * @exception StandardException Thrown on error
135: */
136: public Optimizer getOptimizer(OptimizableList optimizableList,
137: OptimizablePredicateList predList,
138: DataDictionary dDictionary,
139: RequiredRowOrdering requiredRowOrdering,
140: int numTablesInQuery, LanguageConnectionContext lcc)
141: throws StandardException {
142: /* Get/set up the array of join strategies.
143: * See comment in boot(). If joinStrategySet
144: * is null, then we may do needless allocations
145: * in a multi-user environment if multiple
146: * users find it null on entry. However,
147: * assignment of array is atomic, so system
148: * will be consistent even in rare case
149: * where users get different arrays.
150: */
151: if (joinStrategySet == null) {
152: JoinStrategy[] jss = new JoinStrategy[2];
153: jss[0] = new NestedLoopJoinStrategy();
154: jss[1] = new HashJoinStrategy();
155: joinStrategySet = jss;
156: }
157:
158: return getOptimizerImpl(optimizableList, predList, dDictionary,
159: requiredRowOrdering, numTablesInQuery, lcc);
160: }
161:
162: /**
163: * @see OptimizerFactory#getCostEstimate
164: *
165: * @exception StandardException Thrown on error
166: */
167: public CostEstimate getCostEstimate() throws StandardException {
168: return new CostEstimateImpl();
169: }
170:
171: /**
172: * @see OptimizerFactory#supportsOptimizerTrace
173: */
174: public boolean supportsOptimizerTrace() {
175: return false;
176: }
177:
178: //
179: // class interface
180: //
181: public OptimizerFactoryImpl() {
182: }
183:
184: protected Optimizer getOptimizerImpl(
185: OptimizableList optimizableList,
186: OptimizablePredicateList predList,
187: DataDictionary dDictionary,
188: RequiredRowOrdering requiredRowOrdering,
189: int numTablesInQuery, LanguageConnectionContext lcc)
190: throws StandardException {
191:
192: return new OptimizerImpl(optimizableList, predList,
193: dDictionary, ruleBasedOptimization, noTimeout,
194: useStatistics, maxMemoryPerTable, joinStrategySet, lcc
195: .getLockEscalationThreshold(),
196: requiredRowOrdering, numTablesInQuery);
197: }
198:
199: /**
200: * @see OptimizerFactory#getMaxMemoryPerTable
201: */
202: public int getMaxMemoryPerTable() {
203: return maxMemoryPerTable;
204: }
205: }
|