0001: /*
0002:
0003: Derby - Class org.apache.derby.impl.sql.compile.QueryTreeNode
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to you under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derby.impl.sql.compile;
0023:
0024: import org.apache.derby.iapi.sql.execute.ExecutionFactory;
0025: import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
0026: import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
0027: import org.apache.derby.impl.sql.execute.GenericConstantActionFactory;
0028: import org.apache.derby.impl.sql.execute.GenericExecutionFactory;
0029: import org.apache.derby.iapi.util.ByteArray;
0030: import org.apache.derby.iapi.services.loader.ClassFactory;
0031: import org.apache.derby.iapi.services.loader.ClassInspector;
0032: import org.apache.derby.iapi.services.loader.GeneratedClass;
0033: import org.apache.derby.iapi.services.context.ContextManager;
0034: import org.apache.derby.iapi.services.compiler.MethodBuilder;
0035: import org.apache.derby.iapi.services.monitor.Monitor;
0036: import org.apache.derby.iapi.services.sanity.SanityManager;
0037: import org.apache.derby.iapi.services.io.StoredFormatIds;
0038: import org.apache.derby.iapi.error.StandardException;
0039: import org.apache.derby.iapi.sql.compile.CompilerContext;
0040: import org.apache.derby.iapi.sql.compile.NodeFactory;
0041: import org.apache.derby.iapi.sql.compile.Parser;
0042: import org.apache.derby.iapi.sql.compile.Visitable;
0043: import org.apache.derby.iapi.sql.compile.Visitor;
0044: import org.apache.derby.iapi.sql.compile.C_NodeTypes;
0045: import org.apache.derby.iapi.sql.compile.NodeFactory;
0046: import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0047: import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;
0048: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
0049: import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
0050: import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
0051: import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
0052: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
0053: import org.apache.derby.iapi.reference.SQLState;
0054: import org.apache.derby.iapi.sql.execute.ConstantAction;
0055: import org.apache.derby.iapi.types.DataTypeDescriptor;
0056: import org.apache.derby.iapi.types.TypeId;
0057: import org.apache.derby.iapi.types.DataValueDescriptor;
0058: import org.apache.derby.iapi.sql.compile.TypeCompiler;
0059: import org.apache.derby.iapi.sql.ResultDescription;
0060: import org.apache.derby.iapi.sql.StatementType;
0061: import org.apache.derby.iapi.sql.Activation;
0062: import org.apache.derby.iapi.services.classfile.VMOpcode;
0063: import org.apache.derby.iapi.sql.depend.DependencyManager;
0064: import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
0065: import org.apache.derby.catalog.AliasInfo;
0066: import org.apache.derby.catalog.types.SynonymAliasInfo;
0067: import java.util.Properties;
0068: import java.util.Vector;
0069: import java.sql.Types;
0070: import org.apache.derby.iapi.reference.ClassName;
0071:
0072: /**
0073: * QueryTreeNode is the root class for all query tree nodes. All
0074: * query tree nodes inherit from QueryTreeNode except for those that extend
0075: * QueryTreeNodeVector.
0076: *
0077: * @author Jeff Lichtman
0078: */
0079:
0080: public abstract class QueryTreeNode implements Visitable {
0081: public static final int AUTOINCREMENT_START_INDEX = 0;
0082: public static final int AUTOINCREMENT_INC_INDEX = 1;
0083: public static final int AUTOINCREMENT_IS_AUTOINCREMENT_INDEX = 2;
0084: //Parser uses this static field to make a note if the autoincrement column
0085: //is participating in create or alter table.
0086: public static final int AUTOINCREMENT_CREATE_MODIFY = 3;
0087:
0088: private int beginOffset = -1; // offset into SQL input of the substring
0089: // which this query node encodes.
0090: private int endOffset = -1;
0091:
0092: private int nodeType;
0093: private ContextManager cm;
0094: private LanguageConnectionContext lcc;
0095: private GenericConstantActionFactory constantActionFactory;
0096:
0097: /**
0098: * In Derby SQL Standard Authorization, views, triggers and constraints
0099: * execute with definer's privileges. Taking a specific eg of views
0100: * user1
0101: * create table t1 (c11 int);
0102: * create view v1 as select * from user1.t1;
0103: * grant select on v1 to user2;
0104: * user2
0105: * select * from user1.v1;
0106: * Running with definer's privileges mean that since user2 has select
0107: * privileges on view v1 owned by user1, then that is sufficient for user2
0108: * to do a select from view v1. View v1 underneath might access some
0109: * objects that user2 doesn't have privileges on, but that is not a problem
0110: * since views execute with definer's privileges. In order to implement this
0111: * behavior, when doing a select from view v1, we only want to check for
0112: * select privilege on view v1. While processing the underlying query for
0113: * view v1, we want to stop collecting the privilege requirements for the
0114: * query underneath. Following flag, isPrivilegeCollectionRequired is used
0115: * for this purpose. The flag will be true when we are the top level of view
0116: * and then it is turned off while we process the query underlying the view
0117: * v1.
0118: */
0119: boolean isPrivilegeCollectionRequired = true;
0120:
0121: /**
0122: * Set the ContextManager for this node.
0123: *
0124: * @param cm The ContextManager.
0125: */
0126: public void setContextManager(ContextManager cm) {
0127: this .cm = cm;
0128:
0129: if (SanityManager.DEBUG) {
0130: SanityManager.ASSERT(cm != null,
0131: "cm not expected to be null");
0132: }
0133: }
0134:
0135: /**
0136: * Get the current ContextManager.
0137: *
0138: * @return The current ContextManager.
0139: */
0140: public final ContextManager getContextManager() {
0141: if (SanityManager.DEBUG) {
0142: if (cm == null)
0143: SanityManager
0144: .THROWASSERT("Null context manager in QueryTreeNode of type :"
0145: + this .getClass());
0146: }
0147: return cm;
0148: }
0149:
0150: /**
0151: * Gets the NodeFactory for this database.
0152: *
0153: * @return the node factory for this database.
0154: *
0155: */
0156: public final NodeFactory getNodeFactory() {
0157: return getLanguageConnectionContext()
0158: .getLanguageConnectionFactory().getNodeFactory();
0159: }
0160:
0161: /**
0162: * Gets the constant action factory for this database.
0163: *
0164: * @return the constant action factory.
0165: */
0166: public final GenericConstantActionFactory getGenericConstantActionFactory() {
0167: if (constantActionFactory == null) {
0168: GenericExecutionFactory execFactory = (GenericExecutionFactory) getExecutionFactory();
0169: constantActionFactory = execFactory
0170: .getConstantActionFactory();
0171: }
0172:
0173: return constantActionFactory;
0174: }
0175:
0176: public final ExecutionFactory getExecutionFactory() {
0177: ExecutionFactory ef = getLanguageConnectionContext()
0178: .getLanguageConnectionFactory().getExecutionFactory();
0179:
0180: return ef;
0181: }
0182:
0183: /**
0184: Get the ClassFactory to use with this database.
0185: */
0186: protected final ClassFactory getClassFactory() {
0187: return getLanguageConnectionContext()
0188: .getLanguageConnectionFactory().getClassFactory();
0189: }
0190:
0191: /**
0192: * Gets the LanguageConnectionContext for this connection.
0193: *
0194: * @return the lcc for this connection
0195: *
0196: */
0197: protected final LanguageConnectionContext getLanguageConnectionContext() {
0198: if (lcc == null) {
0199: lcc = (LanguageConnectionContext) getContextManager()
0200: .getContext(LanguageConnectionContext.CONTEXT_ID);
0201: }
0202: return lcc;
0203: }
0204:
0205: /**
0206: * Get the name of the SPS that is used
0207: * to execute this statement. Only relevant
0208: * for an ExecSPSNode -- otherwise, returns null.
0209: *
0210: * @return the name of the underlying sps
0211: */
0212: public String getSPSName() {
0213: return null;
0214: }
0215:
0216: /**
0217: * Gets the beginning offset of the SQL substring which this
0218: * query node represents.
0219: *
0220: * @return The beginning offset of the SQL substring. -1 means unknown.
0221: *
0222: */
0223: public int getBeginOffset() {
0224: return beginOffset;
0225: }
0226:
0227: /**
0228: * Sets the beginning offset of the SQL substring which this
0229: * query node represents.
0230: *
0231: * @param beginOffset The beginning offset of the SQL substring.
0232: *
0233: */
0234: public void setBeginOffset(int beginOffset) {
0235: this .beginOffset = beginOffset;
0236: }
0237:
0238: /**
0239: * Gets the ending offset of the SQL substring which this
0240: * query node represents.
0241: *
0242: * @return The ending offset of the SQL substring. -1 means unknown.
0243: *
0244: */
0245: public int getEndOffset() {
0246: return endOffset;
0247: }
0248:
0249: /**
0250: * Sets the ending offset of the SQL substring which this
0251: * query node represents.
0252: *
0253: * @param endOffset The ending offset of the SQL substring.
0254: *
0255: */
0256: public void setEndOffset(int endOffset) {
0257: this .endOffset = endOffset;
0258: }
0259:
0260: /**
0261: * Return header information for debug printing of this query
0262: * tree node.
0263: *
0264: * @return Header information for debug printing of this query
0265: * tree node.
0266: */
0267:
0268: protected String nodeHeader() {
0269: if (SanityManager.DEBUG) {
0270: return "\n" + this .getClass().getName() + '@'
0271: + Integer.toHexString(hashCode()) + "\n";
0272: } else {
0273: return "";
0274: }
0275: }
0276:
0277: /**
0278: * Format a node that has been converted to a String for printing
0279: * as part of a tree. This method indents the String to the given
0280: * depth by inserting tabs at the beginning of the string, and also
0281: * after every newline.
0282: *
0283: * @param nodeString The node formatted as a String
0284: * @param depth The depth to indent the given node
0285: *
0286: * @return The node String reformatted with tab indentation
0287: */
0288:
0289: public static String formatNodeString(String nodeString, int depth) {
0290: if (SanityManager.DEBUG) {
0291: StringBuffer nodeStringBuffer = new StringBuffer(nodeString);
0292: int pos;
0293: char c;
0294: char[] indent = new char[depth];
0295:
0296: /*
0297: ** Form an array of tab characters for indentation.
0298: */
0299: while (depth > 0) {
0300: indent[depth - 1] = '\t';
0301: depth--;
0302: }
0303:
0304: /* Indent the beginning of the string */
0305: nodeStringBuffer.insert(0, indent);
0306:
0307: /*
0308: ** Look for newline characters, except for the last character.
0309: ** We don't want to indent after the last newline.
0310: */
0311: for (pos = 0; pos < nodeStringBuffer.length() - 1; pos++) {
0312: c = nodeStringBuffer.charAt(pos);
0313: if (c == '\n') {
0314: /* Indent again after each newline */
0315: nodeStringBuffer.insert(pos + 1, indent);
0316: }
0317: }
0318:
0319: return nodeStringBuffer.toString();
0320: } else {
0321: return "";
0322: }
0323: }
0324:
0325: /**
0326: * Print this tree for debugging purposes. This recurses through
0327: * all the sub-nodes and prints them indented by their depth in
0328: * the tree.
0329: */
0330:
0331: public void treePrint() {
0332: if (SanityManager.DEBUG) {
0333: debugPrint(nodeHeader());
0334: debugPrint(formatNodeString(this .toString(), 0));
0335: printSubNodes(0);
0336: debugFlush();
0337: }
0338: }
0339:
0340: /**
0341: * Print this tree for debugging purposes. This recurses through
0342: * all the sub-nodes and prints them indented by their depth in
0343: * the tree, starting with the given indentation.
0344: *
0345: * @param depth The depth of this node in the tree, thus,
0346: * the amount to indent it when printing it.
0347: */
0348:
0349: public void treePrint(int depth) {
0350: if (SanityManager.DEBUG) {
0351: debugPrint(formatNodeString(nodeHeader(), depth));
0352: debugPrint(formatNodeString(this .toString(), depth));
0353: printSubNodes(depth);
0354: }
0355: }
0356:
0357: /**
0358: * Print a String for debugging
0359: *
0360: * @param outputString The String to print
0361: */
0362:
0363: public static void debugPrint(String outputString) {
0364: if (SanityManager.DEBUG) {
0365: SanityManager.GET_DEBUG_STREAM().print(outputString);
0366: }
0367: }
0368:
0369: /**
0370: * Flush the debug stream out
0371: */
0372: protected static void debugFlush() {
0373: if (SanityManager.DEBUG) {
0374: SanityManager.GET_DEBUG_STREAM().flush();
0375: }
0376: }
0377:
0378: /**
0379: * Print the sub-nodes of this node.
0380: *
0381: * Each sub-class of QueryTreeNode is expected to provide its own
0382: * printSubNodes() method. In each case, it calls super.printSubNodes(),
0383: * passing along its depth, to get the sub-nodes of the super-class.
0384: * Then it prints its own sub-nodes by calling treePrint() on each
0385: * of its members that is a type of QueryTreeNode. In each case where
0386: * it calls treePrint(), it should pass "depth + 1" to indicate that
0387: * the sub-node should be indented one more level when printing.
0388: * Also, it should call printLabel() to print the name of each sub-node
0389: * before calling treePrint() on the sub-node, so that the reader of
0390: * the printed tree can tell what the sub-node is.
0391: *
0392: * This printSubNodes() exists in here merely to act as a backstop.
0393: * In other words, the calls to printSubNodes() move up the type
0394: * hierarchy, and in this node the calls stop.
0395: *
0396: * I would have liked to put the call to super.printSubNodes() in
0397: * this super-class, but Java resolves "super" statically, so it
0398: * wouldn't get to the right super-class.
0399: *
0400: * @param depth The depth to indent the sub-nodes
0401: */
0402:
0403: public void printSubNodes(int depth) {
0404: }
0405:
0406: /**
0407: * Format this node as a string
0408: *
0409: * Each sub-class of QueryTreeNode should implement its own toString()
0410: * method. In each case, toString() should format the class members
0411: * that are not sub-types of QueryTreeNode (printSubNodes() takes care
0412: * of following the references to sub-nodes, and toString() takes care
0413: * of all members that are not sub-nodes). Newlines should be used
0414: * liberally - one good way to do this is to have a newline at the
0415: * end of each formatted member. It's also a good idea to put the
0416: * name of each member in front of the formatted value. For example,
0417: * the code might look like:
0418: *
0419: * "memberName: " + memberName + "\n" + ...
0420: *
0421: * @return This node formatted as a String
0422: */
0423:
0424: public String toString() {
0425: return "";
0426: }
0427:
0428: /**
0429: * Print the given label at the given indentation depth.
0430: *
0431: * @param depth The depth of indentation to use when printing
0432: * the label
0433: * @param label The String to print
0434: */
0435:
0436: public void printLabel(int depth, String label) {
0437: if (SanityManager.DEBUG) {
0438: debugPrint(formatNodeString(label, depth));
0439: }
0440: }
0441:
0442: /**
0443: * Perform the binding operation on a query tree. Binding consists of
0444: * permissions checking, view resolution, datatype resolution, and
0445: * creation of a dependency list (for determining whether a tree or
0446: * plan is still up to date).
0447: *
0448: * This bind() method does nothing. Each node type that can appear
0449: * at the top of a tree can override this method with its own bind()
0450: * method that does "something".
0451: *
0452: * @return The bound query tree
0453: *
0454: * @exception StandardException Thrown on error
0455: */
0456:
0457: public QueryTreeNode bind() throws StandardException {
0458: return this ;
0459: }
0460:
0461: /**
0462: * Return true if the node references SESSION schema tables (temporary or permanent)
0463: *
0464: * @return true if references SESSION schema tables, else false
0465: *
0466: * @exception StandardException Thrown on error
0467: */
0468: public boolean referencesSessionSchema() throws StandardException {
0469: return false;
0470: }
0471:
0472: /**
0473: * Checks if the passed schema descriptor is for SESSION schema
0474: *
0475: * @return true if the passed schema descriptor is for SESSION schema
0476: *
0477: * @exception StandardException Thrown on error
0478: */
0479: final boolean isSessionSchema(SchemaDescriptor sd) {
0480: return isSessionSchema(sd.getSchemaName());
0481: }
0482:
0483: /**
0484: * Checks if the passed schema name is for SESSION schema
0485: *
0486: * @return true if the passed schema name is for SESSION schema
0487: *
0488: * @exception StandardException Thrown on error
0489: */
0490: final boolean isSessionSchema(String schemaName) {
0491: return SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME
0492: .equals(schemaName);
0493: }
0494:
0495: /**
0496: * Triggers, constraints and views get executed with their definer's
0497: * privileges and they can exist in the system only if their definers'
0498: * still have all the privileges to creeate them. Based on this, any
0499: * time a trigger/view/constraint is executing, we do not need to waste
0500: * time in checking if the definer still has the right set of privileges.
0501: * At compile time, we wil make sure that we do not collect the privilege
0502: * requirement for objects accessed with definer privileges by calling the
0503: * following method.
0504: */
0505: public void disablePrivilegeCollection() {
0506: isPrivilegeCollectionRequired = false;
0507: }
0508:
0509: /**
0510: * Return true from this method means that we need to collect privilege
0511: * requirement for this node. For following cases, this method will
0512: * return true.
0513: * 1)execute view - collect privilege to access view but do not collect
0514: * privilege requirements for objects accessed by actual view uqery
0515: * 2)execute select - collect privilege requirements for objects accessed
0516: * by select statement
0517: * 3)create view - collect privileges for select statement : the select
0518: * statement for create view falls under 2) category above.
0519: *
0520: * @return true if need to collect privilege requirement for this node
0521: */
0522: public boolean isPrivilegeCollectionRequired() {
0523: return (isPrivilegeCollectionRequired);
0524: }
0525:
0526: /**
0527: * Get the optimizer's estimate of the number of rows returned or affected
0528: * for an optimized QueryTree.
0529: *
0530: * For non-optimizable statements (for example, CREATE TABLE),
0531: * return 0. For optimizable statements, this method will be
0532: * over-ridden in the statement's root node (DMLStatementNode
0533: * in all cases we know about so far).
0534: *
0535: * @return 0L
0536: */
0537:
0538: public long getRowEstimate() {
0539: return 0L;
0540: }
0541:
0542: /**
0543: * Generates an optimized QueryTree from a bound QueryTree. Actually,
0544: * it annotates the tree in place rather than generating a new tree,
0545: * but this interface allows the root node of the optmized QueryTree
0546: * to be different from the root node of the bound QueryTree.
0547: *
0548: * For non-optimizable statements (for example, CREATE TABLE),
0549: * return the bound tree without doing anything. For optimizable
0550: * statements, this method will be over-ridden in the statement's
0551: * root node (DMLStatementNode in all cases we know about so far).
0552: *
0553: * Throws an exception if the tree is not bound, or if the binding
0554: * is out of date.
0555: *
0556: * @return An optimized QueryTree
0557: *
0558: * @exception StandardException Thrown on error
0559: */
0560: public QueryTreeNode optimize() throws StandardException {
0561: return this ;
0562: }
0563:
0564: /**
0565: * this implementation of generate() is
0566: * a place-holder until all of the nodes that need to,
0567: * implement it. Only the root, statement nodes
0568: * implement this flavor of generate; the other nodes
0569: * will implement the version that returns Generators
0570: * and takes an activation class builder as an
0571: * argument.
0572: *
0573: * @param ignored - ignored (he he)
0574: *
0575: * @return A GeneratedClass for this statement
0576: *
0577: * @exception StandardException Thrown on error
0578: */
0579: public GeneratedClass generate(ByteArray ignored)
0580: throws StandardException {
0581: throw StandardException.newException(
0582: SQLState.LANG_UNABLE_TO_GENERATE, this .nodeHeader());
0583: }
0584:
0585: /**
0586: * Do the code generation for this node. This is a place-holder
0587: * method - it should be over-ridden in the sub-classes.
0588: *
0589: * @param acb The ActivationClassBuilder for the class being built
0590: * @param mb The method for the generated code to go into
0591: *
0592: * @exception StandardException Thrown on error
0593: */
0594:
0595: protected void generate(ActivationClassBuilder acb, MethodBuilder mb)
0596: throws StandardException {
0597: throw StandardException.newException(
0598: SQLState.LANG_UNABLE_TO_GENERATE, this .nodeHeader());
0599: }
0600:
0601: /**
0602: * Only DML statements have result descriptions - for all others
0603: * return null. This method is overridden in DMLStatementNode.
0604: *
0605: * @return null
0606: *
0607: * @exception StandardException never actually thrown here,
0608: * but thrown by subclasses
0609: */
0610: public ResultDescription makeResultDescription()
0611: throws StandardException {
0612: return null;
0613: }
0614:
0615: /**
0616: * Parameter info is stored in the compiler context.
0617: * Hide this from the callers.
0618: *
0619: *
0620: * @return null
0621: *
0622: * @exception StandardException on error
0623: */
0624: public DataTypeDescriptor[] getParameterTypes()
0625: throws StandardException {
0626: return getCompilerContext().getParameterTypes();
0627: }
0628:
0629: /**
0630: * This creates a class that will do the work that's constant
0631: * across all Executions of a PreparedStatement. It's up to
0632: * our subclasses to override this method if they need to compile
0633: * constant actions into PreparedStatements.
0634: *
0635: * @exception StandardException Thrown on failure
0636: */
0637: public ConstantAction makeConstantAction() throws StandardException {
0638: return null;
0639: }
0640:
0641: /**
0642: * Returns whether or not this Statement requires a set/clear savepoint
0643: * around its execution. The following statement "types" do not require them:
0644: * Cursor - unnecessary and won't work in a read only environment
0645: * Xact - savepoint will get blown away underneath us during commit/rollback
0646: * <p>
0647: * ONLY CALLABLE AFTER GENERATION
0648: *
0649: * @return boolean Whether or not this Statement requires a set/clear savepoint
0650: */
0651: public boolean needsSavepoint() {
0652: return true;
0653: }
0654:
0655: /**
0656: * Returns the name of statement in EXECUTE STATEMENT command.
0657: * Returns null for all other commands.
0658: * @return String null unless overridden for Execute Statement command
0659: */
0660: public String executeStatementName() {
0661: return null;
0662: }
0663:
0664: /**
0665: * Returns name of schema in EXECUTE STATEMENT command.
0666: * Returns null for all other commands.
0667: * @return String schema for EXECUTE STATEMENT null for all others
0668: */
0669: public String executeSchemaName() {
0670: return null;
0671: }
0672:
0673: /**
0674: * Set the node type for this node.
0675: *
0676: * @param nodeType The node type.
0677: */
0678: public void setNodeType(int nodeType) {
0679: this .nodeType = nodeType;
0680: }
0681:
0682: protected int getNodeType() {
0683: return nodeType;
0684: }
0685:
0686: /**
0687: * For final nodes, return whether or not
0688: * the node represents the specified nodeType.
0689: *
0690: * @param nodeType The nodeType of interest.
0691: *
0692: * @return Whether or not
0693: * the node represents the specified nodeType.
0694: */
0695: protected boolean isInstanceOf(int nodeType) {
0696: return (this .nodeType == nodeType);
0697: }
0698:
0699: /**
0700: * Get the DataDictionary
0701: *
0702: * @return The DataDictionary
0703: *
0704: */
0705: public final DataDictionary getDataDictionary() {
0706: return getLanguageConnectionContext().getDataDictionary();
0707: }
0708:
0709: public final DependencyManager getDependencyManager() {
0710: return getDataDictionary().getDependencyManager();
0711: }
0712:
0713: /**
0714: * Get the CompilerContext
0715: *
0716: * @return The CompilerContext
0717: */
0718: protected final CompilerContext getCompilerContext() {
0719: return (CompilerContext) getContextManager().getContext(
0720: CompilerContext.CONTEXT_ID);
0721: }
0722:
0723: /**
0724: * Get the TypeCompiler associated with the given TypeId
0725: *
0726: * @param typeId The TypeId to get a TypeCompiler for
0727: *
0728: * @return The corresponding TypeCompiler
0729: *
0730: */
0731: protected final TypeCompiler getTypeCompiler(TypeId typeId) {
0732: return getCompilerContext().getTypeCompilerFactory()
0733: .getTypeCompiler(typeId);
0734: }
0735:
0736: /**
0737: * Accept a visitor, and call v.visit()
0738: * on child nodes as necessary.
0739: *
0740: * @param v the visitor
0741: *
0742: * @exception StandardException on error
0743: */
0744: public Visitable accept(Visitor v) throws StandardException {
0745: return v.visit(this );
0746: }
0747:
0748: /**
0749: * Get the int value of a Property
0750: *
0751: * @param value Property value as a String
0752: * @param key Key value of property
0753: *
0754: * @return The int value of the property
0755: *
0756: * @exception StandardException Thrown on failure
0757: */
0758: protected int getIntProperty(String value, String key)
0759: throws StandardException {
0760: int intVal = -1;
0761: try {
0762: intVal = Integer.parseInt(value);
0763: } catch (NumberFormatException nfe) {
0764: throw StandardException.newException(
0765: SQLState.LANG_INVALID_NUMBER_FORMAT_FOR_OVERRIDE,
0766: value, key);
0767: }
0768: return intVal;
0769: }
0770:
0771: /**
0772: * Parse some query text and return a parse tree.
0773: *
0774: * @param compilerContext The CompilerContext to use
0775: * @param queryText Query text to parse.
0776: * @param paramDefaults array of parameter defaults used to
0777: * initialize parameter nodes, and ultimately
0778: * for the optimization of statements with
0779: * parameters.
0780: * @param lcc Current LanguageConnectionContext
0781: *
0782: * @return ResultSetNode The parse tree.
0783: *
0784: * @exception StandardException Thrown on error
0785: */
0786: public static QueryTreeNode parseQueryText(
0787: CompilerContext compilerContext, String queryText,
0788: Object[] paramDefaults, LanguageConnectionContext lcc)
0789: throws StandardException {
0790: LanguageConnectionFactory lcf;
0791: Parser p;
0792: QueryTreeNode qtn;
0793:
0794: p = compilerContext.getParser();
0795:
0796: /* Get a Statement to pass to the parser */
0797: lcf = lcc.getLanguageConnectionFactory();
0798:
0799: /* Finally, we can call the parser */
0800: qtn = (QueryTreeNode) p
0801: .parseStatement(queryText, paramDefaults);
0802: return qtn;
0803: }
0804:
0805: /**
0806: * Return the type of statement, something from
0807: * StatementType.
0808: *
0809: * @return the type of statement
0810: */
0811: protected int getStatementType() {
0812: return StatementType.UNKNOWN;
0813: }
0814:
0815: public boolean foundString(String[] list, String search) {
0816: if (list == null) {
0817: return false;
0818: }
0819:
0820: for (int i = 0; i < list.length; i++) {
0821: if (list[i].equals(search)) {
0822: return true;
0823: }
0824: }
0825: return false;
0826: }
0827:
0828: /**
0829: * Get a ConstantNode to represent a typed null value
0830: *
0831: * @param typeId The TypeId of the datatype of the null value
0832: * @param cm The ContextManager
0833: *
0834: * @return A ConstantNode with the specified type, and a value of null
0835: *
0836: * @exception StandardException Thrown on error
0837: */
0838: public ConstantNode getNullNode(TypeId typeId, ContextManager cm)
0839: throws StandardException {
0840: QueryTreeNode constantNode = null;
0841: NodeFactory nf = getNodeFactory();
0842:
0843: switch (typeId.getJDBCTypeId()) {
0844: case Types.VARCHAR:
0845: constantNode = nf.getNode(
0846: C_NodeTypes.VARCHAR_CONSTANT_NODE, typeId, cm);
0847: break;
0848:
0849: case Types.CHAR:
0850: constantNode = nf.getNode(C_NodeTypes.CHAR_CONSTANT_NODE,
0851: typeId, cm);
0852: break;
0853:
0854: case Types.TINYINT:
0855: constantNode = nf.getNode(
0856: C_NodeTypes.TINYINT_CONSTANT_NODE, typeId, cm);
0857: break;
0858:
0859: case Types.SMALLINT:
0860: constantNode = nf.getNode(
0861: C_NodeTypes.SMALLINT_CONSTANT_NODE, typeId, cm);
0862: break;
0863:
0864: case Types.INTEGER:
0865: constantNode = nf.getNode(C_NodeTypes.INT_CONSTANT_NODE,
0866: typeId, cm);
0867: break;
0868:
0869: case Types.BIGINT:
0870: constantNode = nf.getNode(
0871: C_NodeTypes.LONGINT_CONSTANT_NODE, typeId, cm);
0872: break;
0873:
0874: case Types.REAL:
0875: constantNode = nf.getNode(C_NodeTypes.FLOAT_CONSTANT_NODE,
0876: typeId, cm);
0877: break;
0878:
0879: case Types.DOUBLE:
0880: constantNode = nf.getNode(C_NodeTypes.DOUBLE_CONSTANT_NODE,
0881: typeId, cm);
0882: break;
0883:
0884: case Types.NUMERIC:
0885: case Types.DECIMAL:
0886: constantNode = nf.getNode(
0887: C_NodeTypes.DECIMAL_CONSTANT_NODE, typeId, cm);
0888: break;
0889:
0890: case Types.DATE:
0891: case Types.TIME:
0892: case Types.TIMESTAMP:
0893: constantNode = nf.getNode(
0894: C_NodeTypes.USERTYPE_CONSTANT_NODE, typeId, cm);
0895: break;
0896:
0897: case Types.BINARY:
0898: constantNode = nf.getNode(C_NodeTypes.BIT_CONSTANT_NODE,
0899: typeId, cm);
0900: break;
0901:
0902: case Types.VARBINARY:
0903: constantNode = nf.getNode(C_NodeTypes.VARBIT_CONSTANT_NODE,
0904: typeId, cm);
0905: break;
0906:
0907: case Types.LONGVARCHAR:
0908: constantNode = nf.getNode(
0909: C_NodeTypes.LONGVARCHAR_CONSTANT_NODE, typeId, cm);
0910: break;
0911:
0912: case Types.CLOB:
0913: constantNode = nf.getNode(C_NodeTypes.CLOB_CONSTANT_NODE,
0914: typeId, cm);
0915: break;
0916:
0917: case Types.LONGVARBINARY:
0918: constantNode = nf.getNode(
0919: C_NodeTypes.LONGVARBIT_CONSTANT_NODE, typeId, cm);
0920: break;
0921:
0922: case Types.BLOB:
0923: constantNode = nf.getNode(C_NodeTypes.BLOB_CONSTANT_NODE,
0924: typeId, cm);
0925: break;
0926:
0927: case StoredFormatIds.XML_TYPE_ID:
0928: constantNode = nf.getNode(C_NodeTypes.XML_CONSTANT_NODE,
0929: typeId, cm);
0930: break;
0931:
0932: default:
0933: if (typeId.getSQLTypeName().equals("BOOLEAN")) {
0934: constantNode = nf.getNode(
0935: C_NodeTypes.BOOLEAN_CONSTANT_NODE, typeId, cm);
0936: } else if (typeId.userType()) {
0937: constantNode = nf.getNode(
0938: C_NodeTypes.USERTYPE_CONSTANT_NODE, typeId, cm);
0939: } else {
0940: if (SanityManager.DEBUG)
0941: SanityManager.THROWASSERT("Unknown type "
0942: + typeId.getSQLTypeName()
0943: + " in getNullNode");
0944: return null;
0945: }
0946: }
0947:
0948: return (ConstantNode) constantNode;
0949: }
0950:
0951: /**
0952: * Translate a Default node into a default value, given a type descriptor.
0953: *
0954: * @param typeDescriptor A description of the required data type.
0955: *
0956: * @exception StandardException Thrown on error
0957: */
0958: public DataValueDescriptor convertDefaultNode(
0959: DataTypeDescriptor typeDescriptor) throws StandardException {
0960: /*
0961: ** Override in cases where node type
0962: ** can be converted to default value.
0963: */
0964: return null;
0965: }
0966:
0967: /* Initializable methods */
0968:
0969: /**
0970: * Initialize a query tree node.
0971: *
0972: * @exception StandardException Thrown on error
0973: */
0974: public void init(Object arg1) throws StandardException {
0975: if (SanityManager.DEBUG) {
0976: SanityManager
0977: .THROWASSERT("Single-argument init() not implemented for "
0978: + getClass().getName());
0979: }
0980: }
0981:
0982: /**
0983: * Initialize a query tree node.
0984: *
0985: * @exception StandardException Thrown on error
0986: */
0987: public void init(Object arg1, Object arg2) throws StandardException {
0988: if (SanityManager.DEBUG) {
0989: SanityManager
0990: .THROWASSERT("Two-argument init() not implemented for "
0991: + getClass().getName());
0992: }
0993: }
0994:
0995: /**
0996: * Initialize a query tree node.
0997: *
0998: * @exception StandardException Thrown on error
0999: */
1000: public void init(Object arg1, Object arg2, Object arg3)
1001: throws StandardException {
1002: if (SanityManager.DEBUG) {
1003: SanityManager
1004: .THROWASSERT("Three-argument init() not implemented for "
1005: + getClass().getName());
1006: }
1007: }
1008:
1009: /**
1010: * Initialize a query tree node.
1011: *
1012: * @exception StandardException Thrown on error
1013: */
1014: public void init(Object arg1, Object arg2, Object arg3, Object arg4)
1015: throws StandardException {
1016: if (SanityManager.DEBUG) {
1017: SanityManager
1018: .THROWASSERT("Four-argument init() not implemented for "
1019: + getClass().getName());
1020: }
1021: }
1022:
1023: /**
1024: * Initialize a query tree node.
1025: *
1026: * @exception StandardException Thrown on error
1027: */
1028: public void init(Object arg1, Object arg2, Object arg3,
1029: Object arg4, Object arg5) throws StandardException {
1030: if (SanityManager.DEBUG) {
1031: SanityManager
1032: .THROWASSERT("Five-argument init() not implemented for "
1033: + getClass().getName());
1034: }
1035: }
1036:
1037: /**
1038: * Initialize a query tree node.
1039: *
1040: * @exception StandardException Thrown on error
1041: */
1042: public void init(Object arg1, Object arg2, Object arg3,
1043: Object arg4, Object arg5, Object arg6)
1044: throws StandardException {
1045: if (SanityManager.DEBUG) {
1046: SanityManager
1047: .THROWASSERT("Six-argument init() not implemented for "
1048: + getClass().getName());
1049: }
1050: }
1051:
1052: /**
1053: * Initialize a query tree node.
1054: *
1055: * @exception StandardException Thrown on error
1056: */
1057: public void init(Object arg1, Object arg2, Object arg3,
1058: Object arg4, Object arg5, Object arg6, Object arg7)
1059: throws StandardException {
1060: if (SanityManager.DEBUG) {
1061: SanityManager
1062: .THROWASSERT("Seven-argument init() not implemented for "
1063: + getClass().getName());
1064: }
1065: }
1066:
1067: /**
1068: * Initialize a query tree node.
1069: *
1070: * @exception StandardException Thrown on error
1071: */
1072: public void init(Object arg1, Object arg2, Object arg3,
1073: Object arg4, Object arg5, Object arg6, Object arg7,
1074: Object arg8) throws StandardException {
1075: if (SanityManager.DEBUG) {
1076: SanityManager
1077: .THROWASSERT("Eight-argument init() not implemented for "
1078: + getClass().getName());
1079: }
1080: }
1081:
1082: /**
1083: * Initialize a query tree node.
1084: *
1085: * @exception StandardException Thrown on error
1086: */
1087: public void init(Object arg1, Object arg2, Object arg3,
1088: Object arg4, Object arg5, Object arg6, Object arg7,
1089: Object arg8, Object arg9) throws StandardException {
1090: if (SanityManager.DEBUG) {
1091: SanityManager
1092: .THROWASSERT("Nine-argument init() not implemented for "
1093: + getClass().getName());
1094: }
1095: }
1096:
1097: /**
1098: * Initialize a query tree node.
1099: *
1100: * @exception StandardException Thrown on error
1101: */
1102: public void init(Object arg1, Object arg2, Object arg3,
1103: Object arg4, Object arg5, Object arg6, Object arg7,
1104: Object arg8, Object arg9, Object arg10)
1105: throws StandardException {
1106: if (SanityManager.DEBUG) {
1107: SanityManager
1108: .THROWASSERT("Ten-argument init() not implemented for "
1109: + getClass().getName());
1110: }
1111: }
1112:
1113: /**
1114: * Initialize a query tree node.
1115: *
1116: * @exception StandardException Thrown on error
1117: */
1118: public void init(Object arg1, Object arg2, Object arg3,
1119: Object arg4, Object arg5, Object arg6, Object arg7,
1120: Object arg8, Object arg9, Object arg10, Object arg11)
1121: throws StandardException {
1122: if (SanityManager.DEBUG) {
1123: SanityManager
1124: .THROWASSERT("Eleven-argument init() not implemented for "
1125: + getClass().getName());
1126: }
1127: }
1128:
1129: /**
1130: * Initialize a query tree node.
1131: *
1132: * @exception StandardException Thrown on error
1133: */
1134: public void init(Object arg1, Object arg2, Object arg3,
1135: Object arg4, Object arg5, Object arg6, Object arg7,
1136: Object arg8, Object arg9, Object arg10, Object arg11,
1137: Object arg12) throws StandardException {
1138: if (SanityManager.DEBUG) {
1139: SanityManager
1140: .THROWASSERT("Twelve-argument init() not implemented for "
1141: + getClass().getName());
1142: }
1143: }
1144:
1145: /**
1146: * Initialize a query tree node.
1147: *
1148: * @exception StandardException Thrown on error
1149: */
1150: public void init(Object arg1, Object arg2, Object arg3,
1151: Object arg4, Object arg5, Object arg6, Object arg7,
1152: Object arg8, Object arg9, Object arg10, Object arg11,
1153: Object arg12, Object arg13) throws StandardException {
1154: if (SanityManager.DEBUG) {
1155: SanityManager
1156: .THROWASSERT("Thirteen-argument init() not implemented for "
1157: + getClass().getName());
1158: }
1159: }
1160:
1161: /**
1162: * Initialize a query tree node.
1163: *
1164: * @exception StandardException Thrown on error
1165: */
1166: public void init(Object arg1, Object arg2, Object arg3,
1167: Object arg4, Object arg5, Object arg6, Object arg7,
1168: Object arg8, Object arg9, Object arg10, Object arg11,
1169: Object arg12, Object arg13, Object arg14)
1170: throws StandardException {
1171: if (SanityManager.DEBUG) {
1172: SanityManager
1173: .THROWASSERT("Fourteen-argument init() not implemented for "
1174: + getClass().getName());
1175: }
1176: }
1177:
1178: public TableName makeTableName(String schemaName, String flatName)
1179: throws StandardException {
1180: return (TableName) getNodeFactory().getNode(
1181: C_NodeTypes.TABLE_NAME, schemaName, flatName,
1182: getContextManager());
1183: }
1184:
1185: public boolean isAtomic() throws StandardException {
1186: if (SanityManager.DEBUG) {
1187: SanityManager
1188: .THROWASSERT("isAtomic should not be called for this class: "
1189: + getClass().getName());
1190: }
1191:
1192: return false;
1193: }
1194:
1195: public Object getCursorInfo() throws StandardException {
1196: return null;
1197: }
1198:
1199: /**
1200: * Get the descriptor for the named table within the given schema.
1201: * If the schema parameter is NULL, it looks for the table in the
1202: * current (default) schema. Table descriptors include object ids,
1203: * object types (table, view, etc.)
1204: * If the schema is SESSION, then before looking into the data dictionary
1205: * for persistent tables, it first looks into LCC for temporary tables.
1206: * If no temporary table tableName found for the SESSION schema, then it goes and
1207: * looks through the data dictionary for persistent table
1208: * We added getTableDescriptor here so that we can look for non data dictionary
1209: * tables(ie temp tables) here. Any calls to getTableDescriptor in data dictionary
1210: * should be only for persistent tables
1211: *
1212: * @param tableName The name of the table to get the descriptor for
1213: * @param schema The descriptor for the schema the table lives in.
1214: * If null, use the current (default) schema.
1215: *
1216: * @return The descriptor for the table, null if table does not
1217: * exist.
1218: *
1219: * @exception StandardException Thrown on failure
1220: */
1221: protected final TableDescriptor getTableDescriptor(
1222: String tableName, SchemaDescriptor schema)
1223: throws StandardException {
1224: TableDescriptor retval;
1225:
1226: //Following if means we are dealing with SESSION schema.
1227: if (isSessionSchema(schema)) {
1228: //First we need to look in the list of temporary tables to see if this table is a temporary table.
1229: retval = getLanguageConnectionContext()
1230: .getTableDescriptorForDeclaredGlobalTempTable(
1231: tableName);
1232: if (retval != null)
1233: return retval; //this is a temporary table
1234: }
1235:
1236: //Following if means we are dealing with SESSION schema and we are dealing with in-memory schema (ie there is no physical SESSION schema)
1237: //If following if is true, it means SESSION.table is not a declared table & it can't be physical SESSION.table
1238: //because there is no physical SESSION schema
1239: if (schema.getUUID() == null)
1240: return null;
1241:
1242: //it is not a temporary table, so go through the data dictionary to find the physical persistent table
1243: TableDescriptor td = getDataDictionary().getTableDescriptor(
1244: tableName, schema);
1245: if (td == null || td.isSynonymDescriptor())
1246: return null;
1247: return td;
1248: }
1249:
1250: /**
1251: * Get the descriptor for the named schema. If the schemaName
1252: * parameter is NULL, it gets the descriptor for the current (default)
1253: * schema. Schema descriptors include authorization ids and schema ids.
1254: * SQL92 allows a schema to specify a default character set - we will
1255: * not support this. Will check default schema for a match
1256: * before scanning a system table.
1257: *
1258: * @param schemaName The name of the schema we're interested in.
1259: * If the name is NULL, get the descriptor for the
1260: * current schema.
1261: *
1262: * @return The descriptor for the schema.
1263: *
1264: * @exception StandardException Thrown on error
1265: */
1266: final SchemaDescriptor getSchemaDescriptor(String schemaName)
1267: throws StandardException {
1268: //return getSchemaDescriptor(schemaName, schemaName != null);
1269: return getSchemaDescriptor(schemaName, true);
1270: }
1271:
1272: final SchemaDescriptor getSchemaDescriptor(String schemaName,
1273: boolean raiseError) throws StandardException {
1274: /*
1275: ** Check for a compilation context. Sometimes
1276: ** there is a special compilation context in
1277: ** place to recompile something that may have
1278: ** been compiled against a different schema than
1279: ** the current schema (e.g views):
1280: **
1281: ** CREATE SCHEMA x
1282: ** CREATE TABLE t
1283: ** CREATE VIEW vt as SEELCT * FROM t
1284: ** SET SCHEMA app
1285: ** SELECT * FROM X.vt
1286: **
1287: ** In the above view vt must be compiled against
1288: ** the X schema.
1289: */
1290:
1291: SchemaDescriptor sd = null;
1292: boolean isCurrent = false;
1293: boolean isCompilation = false;
1294: if (schemaName == null) {
1295:
1296: CompilerContext cc = getCompilerContext();
1297: sd = cc.getCompilationSchema();
1298:
1299: if (sd == null) {
1300: // Set the compilation schema to be the default,
1301: // notes that this query has schema dependencies.
1302: sd = getLanguageConnectionContext().getDefaultSchema();
1303:
1304: isCurrent = true;
1305:
1306: cc.setCompilationSchema(sd);
1307: } else {
1308: isCompilation = true;
1309: }
1310: schemaName = sd.getSchemaName();
1311: }
1312:
1313: DataDictionary dataDictionary = getDataDictionary();
1314: SchemaDescriptor sdCatalog = dataDictionary
1315: .getSchemaDescriptor(schemaName,
1316: getLanguageConnectionContext()
1317: .getTransactionCompile(), raiseError);
1318:
1319: if (isCurrent || isCompilation) {
1320: //if we are dealing with a SESSION schema and it is not physically
1321: //created yet, then it's uuid is going to be null. DERBY-1706
1322: //Without the getUUID null check below, following will give NPE
1323: //set schema session; -- session schema has not been created yet
1324: //create table t1(c11 int);
1325: if (sdCatalog != null && sdCatalog.getUUID() != null) {
1326: // different UUID for default (current) schema than in catalog,
1327: // so reset default schema.
1328: if (!sdCatalog.getUUID().equals(sd.getUUID())) {
1329: if (isCurrent)
1330: getLanguageConnectionContext()
1331: .setDefaultSchema(sdCatalog);
1332: getCompilerContext()
1333: .setCompilationSchema(sdCatalog);
1334: }
1335: } else {
1336: // this schema does not exist, so ensure its UUID is null.
1337: sd.setUUID(null);
1338: sdCatalog = sd;
1339: }
1340: }
1341: return sdCatalog;
1342: }
1343:
1344: /**
1345: * Resolve table/view reference to a synonym. May have to follow a synonym chain.
1346: *
1347: * @param tabName to match for a synonym
1348: *
1349: * @return Synonym TableName if a match is found, NULL otherwise.
1350: *
1351: * @exception StandardException Thrown on error
1352: */
1353: public TableName resolveTableToSynonym(TableName tabName)
1354: throws StandardException {
1355: DataDictionary dd = getDataDictionary();
1356: String nextSynonymTable = tabName.getTableName();
1357: String nextSynonymSchema = tabName.getSchemaName();
1358: boolean found = false;
1359: CompilerContext cc = getCompilerContext();
1360:
1361: // Circular synonym references should have been detected at the DDL time, so
1362: // the following loop shouldn't loop forever.
1363: for (;;) {
1364: SchemaDescriptor nextSD = getSchemaDescriptor(
1365: nextSynonymSchema, false);
1366: if (nextSD == null || nextSD.getUUID() == null)
1367: break;
1368:
1369: AliasDescriptor nextAD = dd.getAliasDescriptor(nextSD
1370: .getUUID().toString(), nextSynonymTable,
1371: AliasInfo.ALIAS_NAME_SPACE_SYNONYM_AS_CHAR);
1372: if (nextAD == null)
1373: break;
1374:
1375: /* Query is dependent on the AliasDescriptor */
1376: cc.createDependency(nextAD);
1377:
1378: found = true;
1379: SynonymAliasInfo info = ((SynonymAliasInfo) nextAD
1380: .getAliasInfo());
1381: nextSynonymTable = info.getSynonymTable();
1382: nextSynonymSchema = info.getSynonymSchema();
1383: }
1384:
1385: if (!found)
1386: return null;
1387:
1388: TableName tableName = new TableName();
1389: tableName.init(nextSynonymSchema, nextSynonymTable);
1390: return tableName;
1391: }
1392:
1393: /**
1394: *
1395: * @param javaClassName The name of the java class to resolve.
1396: *
1397: * @param convertCase whether to convert the case before resolving class alias.
1398: *
1399: * @return Resolved class name or class alias name.
1400: *
1401: * @exception StandardException Thrown on error
1402: */
1403: String verifyClassExist(String javaClassName, boolean convertCase)
1404: throws StandardException {
1405: /* Verify that the class exists */
1406:
1407: ClassInspector classInspector = getClassFactory()
1408: .getClassInspector();
1409:
1410: /* We first try to resolve the javaClassName as a class. If that
1411: * fails then we try to resolve it as a class alias.
1412: */
1413:
1414: Throwable reason = null;
1415: boolean foundMatch = false;
1416: try {
1417:
1418: foundMatch = classInspector.accessible(javaClassName);
1419:
1420: } catch (ClassNotFoundException cnfe) {
1421:
1422: reason = cnfe;
1423: }
1424:
1425: if (!foundMatch)
1426: throw StandardException.newException(
1427: SQLState.LANG_TYPE_DOESNT_EXIST2, reason,
1428: javaClassName);
1429:
1430: if (ClassInspector.primitiveType(javaClassName))
1431: throw StandardException.newException(
1432: SQLState.LANG_TYPE_DOESNT_EXIST3, javaClassName);
1433:
1434: return javaClassName;
1435: }
1436:
1437: /**
1438: * set the Information gathered from the parent table that is
1439: * required to peform a referential action on dependent table.
1440: */
1441: public void setRefActionInfo(long fkIndexConglomId,
1442: int[] fkColArray, String parentResultSetId,
1443: boolean dependentScan) {
1444: if (SanityManager.DEBUG) {
1445: SanityManager
1446: .THROWASSERT("setRefActionInfo() not expected to be called for "
1447: + getClass().getName());
1448: }
1449: }
1450:
1451: /**
1452: Add an authorization check into the passed in method.
1453: */
1454: void generateAuthorizeCheck(ActivationClassBuilder acb,
1455: MethodBuilder mb, int sqlOperation) {
1456: // add code to authorize statement execution.
1457: acb.pushThisAsActivation(mb);
1458: mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
1459: "getLanguageConnectionContext",
1460: ClassName.LanguageConnectionContext, 0);
1461: mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "getAuthorizer",
1462: ClassName.Authorizer, 0);
1463:
1464: acb.pushThisAsActivation(mb);
1465: mb.push(sqlOperation);
1466: mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "authorize",
1467: "void", 2);
1468: }
1469:
1470: }
|