Package org.teiid.query.analysis

Source Code of org.teiid.query.analysis.AnalysisRecord

/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.  Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* 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.
*/

package org.teiid.query.analysis;

import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

import org.teiid.client.plan.Annotation;
import org.teiid.client.plan.PlanNode;
import org.teiid.core.types.DataTypeManager;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.lang.SubqueryContainer;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;


/**
* <p>The AnalysisRecord holds all debug/analysis information for
* a particular query as it is executed.  This includes:</p>
* <UL>
* <LI>Flags indicating what should be recorded</LI>
* <LI>Query plan, if requested</LI>
* <LI>Annotations indicating important decisions, if requested</li>
* <li>Debug trace information, if requested</LI>
* </ul>
*/
public class AnalysisRecord implements Serializable {
 
    // Common
    public static final String PROP_OUTPUT_COLS = "Output Columns"; //$NON-NLS-1$
   
    // Relational
    public static final String PROP_CRITERIA = "Criteria"; //$NON-NLS-1$
    public static final String PROP_SELECT_COLS = "Select Columns"; //$NON-NLS-1$
    public static final String PROP_GROUP_COLS = "Grouping Columns"; //$NON-NLS-1$
    public static final String PROP_SQL = "Query"; //$NON-NLS-1$
    public static final String PROP_MODEL_NAME = "Model Name"; //$NON-NLS-1$
    public static final String PROP_DEPENDENT = "Dependent Join"; //$NON-NLS-1$
    public static final String PROP_JOIN_STRATEGY = "Join Strategy"; //$NON-NLS-1$
    public static final String PROP_JOIN_TYPE = "Join Type"; //$NON-NLS-1$
    public static final String PROP_JOIN_CRITERIA = "Join Criteria"; //$NON-NLS-1$
    public static final String PROP_EXECUTION_PLAN = "Execution Plan"; //$NON-NLS-1$
    public static final String PROP_INTO_GROUP = "Into Target"; //$NON-NLS-1$
    public static final String PROP_SORT_COLS = "Sort Columns"; //$NON-NLS-1$
    public static final String PROP_SORT_MODE = "Sort Mode"; //$NON-NLS-1$
    public static final String PROP_NODE_STATS_LIST = "Statistics"; //$NON-NLS-1$
    public static final String PROP_NODE_COST_ESTIMATES = "Cost Estimates"//$NON-NLS-1$
    public static final String PROP_ROW_OFFSET = "Row Offset"//$NON-NLS-1$
    public static final String PROP_ROW_LIMIT = "Row Limit"//$NON-NLS-1$
    public static final String PROP_WITH = "With"; //$NON-NLS-1$
   
    // XML
    public static final String PROP_MESSAGE = "Message"; //$NON-NLS-1$
    public static final String PROP_TAG = "Tag"; //$NON-NLS-1$
    public static final String PROP_NAMESPACE = "Namespace"; //$NON-NLS-1$
    public static final String PROP_DATA_COL = "Data Column"; //$NON-NLS-1$
    public static final String PROP_NAMESPACE_DECL = "Namespace Declarations"; //$NON-NLS-1$
    public static final String PROP_OPTIONAL = "Optional Flag"; //$NON-NLS-1$
    public static final String PROP_DEFAULT = "Default Value"; //$NON-NLS-1$
    public static final String PROP_RECURSE_DIR = "Recursion Direction"//$NON-NLS-1$
    public static final String PROP_BINDINGS = "Bindings"; //$NON-NLS-1$
    public static final String PROP_IS_STAGING = "Is Staging Flag"; //$NON-NLS-1$
    public static final String PROP_IN_MEMORY = "Source In Memory Flag"; //$NON-NLS-1$
    public static final String PROP_CONDITION = "Condition"; //$NON-NLS-1$
    public static final String PROP_DEFAULT_PROGRAM = "Default Program"; //$NON-NLS-1$
    public static final String PROP_ENCODING = "Encoding"; //$NON-NLS-1$
    public static final String PROP_FORMATTED = "Formatted Flag"; //$NON-NLS-1$
   
    // Procedure
    public static final String PROP_EXPRESSION = "Expression"; //$NON-NLS-1$
    public static final String PROP_RESULT_SET = "Result Set"; //$NON-NLS-1$
    public static final String PROP_PROGRAM = "Program"//$NON-NLS-1$
    public static final String PROP_VARIABLE = "Variable"; //$NON-NLS-1$
    public static final String PROP_THEN = "Then"; //$NON-NLS-1$
    public static final String PROP_ELSE = "Else"; //$NON-NLS-1$

    // Flags regarding what should be recorded
    private boolean recordQueryPlan;
    private boolean recordDebug;
   
    private PlanNode queryPlan;
    // Annotations
    private Collection<Annotation> annotations;
   
    // Debug trace log
    private StringWriter stringWriter;  // inner
    private PrintWriter debugWriter;    // public
   
    public AnalysisRecord(boolean recordQueryPlan, boolean recordDebug) {
      this.recordQueryPlan = recordQueryPlan | LogManager.isMessageToBeRecorded(LogConstants.CTX_QUERY_PLANNER, MessageLevel.DETAIL);
        this.recordDebug = recordDebug | LogManager.isMessageToBeRecorded(LogConstants.CTX_QUERY_PLANNER, MessageLevel.TRACE);
       
        if(this.recordQueryPlan) {
            this.annotations = new ArrayList<Annotation>();
        }
       
        if(this.recordDebug) {
            this.stringWriter = new StringWriter();
            this.debugWriter = new PrintWriter(this.stringWriter);
        }
    }
   
    public static AnalysisRecord createNonRecordingRecord() {
        return new AnalysisRecord(false, false);
    }
   
    public PlanNode getQueryPlan() {
    return queryPlan;
  }
   
    public void setQueryPlan(PlanNode queryPlan) {
    this.queryPlan = queryPlan;
  }

    /**
     * Determine whether query plan should be recorded
     * @return True to record
     */
    public boolean recordQueryPlan() {
        return this.recordQueryPlan;
    }
   
    /**
     * Determine whether annotations should be recorded
     * @return True to record
     */
    public boolean recordAnnotations() {
        return this.recordQueryPlan;
    }
   
    /**
     * Determine whether debug trace log should be recorded
     * @return True to record
     */
    public boolean recordDebug() {
        return this.recordDebug;
    }
   
    /**
     * Add an annotation.  This can only be used if {@link #recordAnnotations}
     * returns true.
     * @param annotation Annotation to add
     */
    public void addAnnotation(Annotation annotation) {
        this.annotations.add(annotation);
    }
   
    /**
     * Get annotations. 
     * @return
     */
    public Collection<Annotation> getAnnotations() {
        return this.annotations;
    }
   
    /**
     * Add line to debug log  This can only be
     * used if {@link #recordDebug} returns true.
     * @param debugLine Text to add to debug writer
     */
    public void println(String debugLine) {
        this.debugWriter.println(debugLine);
    }
   
    /**
     * Get debug trace log recorded to writer.  Typically this is used
     * once at the end of query execution.
     * @return
     */
    public String getDebugLog() {
        if(recordDebug) {
            return this.stringWriter.getBuffer().toString();
        }
        return null;
    }

  /**
   * Helper method to turn a list of projected symbols into a suitable list of
   * output column strings with name and type.
   * @param projectedSymbols The list of SingleElementSymbol projected from a plan or node
   * @return List of output columns for sending to the client as part of the plan
   */               
  public static List<String> getOutputColumnProperties(List<SingleElementSymbol> projectedSymbols) {
      if(projectedSymbols != null) {
          List<String> outputCols = new ArrayList<String>(projectedSymbols.size());
          for(int i=0; i<projectedSymbols.size() ; i++) {
              SingleElementSymbol symbol = projectedSymbols.get(i);
              outputCols.add(symbol.getShortName() + " (" + DataTypeManager.getDataTypeName(symbol.getType()) + ")"); //$NON-NLS-1$ //$NON-NLS-2$
          }
          return outputCols;
      }
      return Collections.emptyList();
  }
 
  public static void addLanaguageObjects(PlanNode node, String key, List<? extends LanguageObject> objects) {
    List<String> values = new ArrayList<String>();
    int index = 0;
    for (LanguageObject languageObject : objects) {
      values.add(languageObject.toString());
      List<SubqueryContainer> subqueries = ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(objects);
      for (ListIterator<SubqueryContainer> iterator = subqueries.listIterator(); iterator.hasNext();) {
        SubqueryContainer subqueryContainer = iterator.next();
        node.addProperty(key + " Subplan " + index++, subqueryContainer.getCommand().getProcessorPlan().getDescriptionProperties()); //$NON-NLS-1$
      }
    }
    node.addProperty(key, values);
  }
}
TOP

Related Classes of org.teiid.query.analysis.AnalysisRecord

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.