⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expression.cs

📁 C#数据库中间层处理,支持主流数据库,如sql、oracle等
💻 CS
📖 第 1 页 / 共 2 页
字号:
/*
 * Expression.cs
 *
 * Copyright (c) 2001, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This package is based on HypersonicSQL, originally developed by Thomas Mueller.
 *
 * C# port by Mark Tutt
 *
 */
namespace SharpHSQL
{
	using System;
	using System.Collections;

	/**
	 * Expression class declaration
	 *
	 *
	 * @version 1.0.0.1
	 */
	class Expression 
	{

		// leaf types
		public const int    VALUE = 1, COLUMN = 2, QUERY = 3, TRUE = 4,
			VALUELIST = 5, ASTERIX = 6, FUNCTION = 7;

		// operations
		public const int    NEGATE = 9, ADD = 10, SUBTRACT = 11, MULTIPLY = 12,
			DIVIDE = 14, CONCAT = 15;

		// logical operations
		public const int    NOT = 20, EQUAL = 21, BIGGER_EQUAL = 22, BIGGER = 23,
			SMALLER = 24, SMALLER_EQUAL = 25, NOT_EQUAL = 26,
			LIKE = 27, AND = 28, OR = 29, IN = 30, EXISTS = 31;

		// aggregate functions
		public const int    COUNT = 40, SUM = 41, MIN = 42, MAX = 43, AVG = 44;

		// system functions
		public const int    IFNULL = 60, CONVERT = 61, CASEWHEN = 62;

		// temporary used during paring
		public const int    PLUS = 100, OPEN = 101, CLOSE = 102, SELECT = 103,
			COMMA = 104, STRINGCONCAT = 105, BETWEEN = 106,
			CAST = 107, END = 108;
		
		private int		iType;

		// nodes

		private Expression  eArg, eArg2;

		// VALUE, VALUELIST
		private object      oData;
		private Hashtable   hList;
		private int		iDataType;

		// QUERY (correlated subquery)

		private Select      sSelect;

		// FUNCTION

		// Needed features of .NET do not exist (Yet)private Function    fFunction;

		// LIKE
		private char	cLikeEscape;

		// COLUMN
		private string      sTable, sColumn;
		private TableFilter tFilter;	// null if not yet resolved
		private int		iColumn;
		private string      sAlias;    // if it is a column of a select column list
		private bool     bDescending;    // if it is a column in a order by

		/**
		 * Constructor declaration
		 *
		 *
		 * @param f
		 */
		/*		Expression(Function f) 
				{
					iType = FUNCTION;
					fFunction = f;
				}
		*/
		/**
		 * Constructor declaration
		 *
		 *
		 * @param e
		 */
		public Expression(Expression e) 
		{
			iType = e.iType;
			iDataType = e.iDataType;
			eArg = e.eArg;
			eArg2 = e.eArg2;
			cLikeEscape = e.cLikeEscape;
			sSelect = e.sSelect;
			//			fFunction = e.fFunction;
		}

		/**
		 * Constructor declaration
		 *
		 *
		 * @param s
		 */
		public Expression(Select s) 
		{
			iType = QUERY;
			sSelect = s;
		}

		/**
		 * Constructor declaration
		 *
		 *
		 * @param v
		 */
		public Expression(ArrayList v) 
		{
			iType = VALUELIST;
			iDataType = Column.VARCHAR;

			int len = v.Count;

			hList = new Hashtable(len);

			for (int i = 0; i < len; i++) 
			{
				object o = v[i];

				if (o != null) 
				{
					hList.Add(o, this);    // todo: don't use such dummy objects
				}
			}
		}

		/**
		 * Constructor declaration
		 *
		 *
		 * @param type
		 * @param e
		 * @param e2
		 */
		public Expression(int type, Expression e, Expression e2) 
		{
			iType = type;
			eArg = e;
			eArg2 = e2;
		}

		/**
		 * Constructor declaration
		 *
		 *
		 * @param table
		 * @param column
		 */
		public Expression(string table, string column) 
		{
			sTable = table;

			if (column == null) 
			{
				iType = ASTERIX;
			} 
			else 
			{
				iType = COLUMN;
				sColumn = column;
			}
		}

		/**
		 * Constructor declaration
		 *
		 *
		 * @param datatype
		 * @param o
		 */
		public Expression(int datatype, object o) 
		{
			iType = VALUE;
			iDataType = datatype;
			oData = o;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @param c
		 */
		public void setLikeEscape(char c) 
		{
			cLikeEscape = c;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @param type
		 */
		public void setDataType(int type) 
		{
			iDataType = type;
		}

		/**
		 * Method declaration
		 *
		 */
		public void setTrue() 
		{
			iType = TRUE;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @return
		 */
		public bool isAggregate() 
		{
			if (iType == COUNT || iType == MAX || iType == MIN || iType == SUM
				|| iType == AVG) 
			{
				return true;
			}

			// todo: recurse eArg and eArg2; maybe they are grouped.
			// grouping 'correctly' would be quite complex
			return false;
		}

		/**
		 * Method declaration
		 *
		 */
		public void setDescending() 
		{
			bDescending = true;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @return
		 */
		public bool isDescending() 
		{
			return bDescending;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @param s
		 */
		public void setAlias(string s) 
		{
			sAlias = s;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @return
		 */
		public string getAlias() 
		{
			if (sAlias != null) 
			{
				return sAlias;
			}

			if (iType == VALUE) 
			{
				return "";
			}

			if (iType == COLUMN) 
			{
				return sColumn;
			}

			// todo
			return "";
		}

		/**
		 * Method declaration
		 *
		 *
		 * @return
		 */
		public int getType() 
		{
			return iType;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @return
		 */
		public int getColumnNr() 
		{
			return iColumn;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @return
		 */
		public Expression getArg() 
		{
			return eArg;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @return
		 */
		public Expression getArg2() 
		{
			return eArg2;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @return
		 */
		public TableFilter getFilter() 
		{
			return tFilter;
		}

		/**
		 * Method declaration
		 *
		 *
		 * @throws Exception
		 */
		public void checkResolved() 
		{
			Trace.check(iType != COLUMN || tFilter != null,
				Trace.COLUMN_NOT_FOUND, sColumn);

			if (eArg != null) 
			{
				eArg.checkResolved();
			}

			if (eArg2 != null) 
			{
				eArg2.checkResolved();
			}

			if (sSelect != null) 
			{
				sSelect.checkResolved();
			}

			/*			if (fFunction != null) 
						{
							fFunction.checkResolved();
						}
			*/		}

		/**
		 * Method declaration
		 *
		 *
		 * @param f
		 *
		 * @throws Exception
		 */
		public void resolve(TableFilter f) 
		{
			if (f != null && iType == COLUMN) 
			{
				if (sTable == null || f.getName().Equals(sTable)) 
				{
					int i = f.getTable().searchColumn(sColumn);

					if (i != -1) 
					{

						// todo: other error message: multiple tables are possible
						Trace.check(tFilter == null || tFilter == f,
							Trace.COLUMN_NOT_FOUND, sColumn);

						tFilter = f;
						iColumn = i;
						sTable = f.getName();
						iDataType = f.getTable().getColumnType(i);
					}
				}
			}

			// currently sets only data type
			// todo: calculate fixed expressions if possible
			if (eArg != null) 
			{
				eArg.resolve(f);
			}

			if (eArg2 != null) 
			{
				eArg2.resolve(f);
			}

			if (sSelect != null) 
			{
				sSelect.resolve(f, false);
				sSelect.resolve();
			}

			/*			if (fFunction != null) 
						{
							fFunction.resolve(f);
						}
			*/
			if (iDataType != 0) 
			{
				return;
			}

			switch (iType) 
			{

					/*				case FUNCTION:
										iDataType = fFunction.getReturnType();

										break;
					*/
				case QUERY:
					iDataType = sSelect.eColumn[0].iDataType;

					break;

				case NEGATE:
					iDataType = eArg.iDataType;

					break;

				case ADD:

				case SUBTRACT:

				case MULTIPLY:

				case DIVIDE:
					iDataType = eArg.iDataType;

					break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -