1 /* 2 * Copyright 2015-2018 HuntLabs.cn 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 module hunt.sql.ast.expr.SQLIdentifierExpr; 17 18 import hunt.sql.SQLUtils; 19 import hunt.sql.ast; 20 import hunt.sql.ast.statement; 21 import hunt.sql.visitor.SQLASTVisitor; 22 import hunt.sql.util.FnvHash; 23 import hunt.collection; 24 import hunt.sql.ast.expr.SQLPropertyExpr; 25 import std.uni; 26 import hunt.String; 27 import hunt.text; 28 import hunt.util.StringBuilder; 29 30 class SQLIdentifierExpr : SQLExprImpl , SQLName { 31 string name; 32 private long _hashCode64; 33 34 private SQLObject resolvedColumn; 35 private SQLObject resolvedOwnerObject; 36 37 this(){ 38 39 } 40 41 this(string name){ 42 this.name = name; 43 } 44 45 this(string name, long hash_lower){ 46 this.name = name; 47 this._hashCode64 = hash_lower; 48 } 49 50 string getSimpleName() { 51 return name; 52 } 53 54 string getLowerName() { 55 if (name is null) { 56 return null; 57 } 58 59 return toLower(name); 60 } 61 62 string getName() { 63 return this.name; 64 } 65 66 void setName(string name) { 67 this.name = name; 68 this._hashCode64 = 0L; 69 70 if (cast(SQLPropertyExpr)parent !is null) { 71 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) parent; 72 propertyExpr.computeHashCode64(); 73 } 74 } 75 76 long nameHashCode64() { 77 return hashCode64(); 78 } 79 80 override 81 long hashCode64() { 82 if (_hashCode64 == 0 83 && name !is null) { 84 _hashCode64 = FnvHash.hashCode64(name); 85 } 86 return _hashCode64; 87 } 88 89 override void output(StringBuilder buf) { 90 buf.append(this.name); 91 } 92 93 override protected void accept0(SQLASTVisitor visitor) { 94 visitor.visit(this); 95 96 visitor.endVisit(this); 97 } 98 99 override 100 size_t toHash() @trusted nothrow { 101 long value ; 102 try 103 { 104 value = hashCode64(); 105 } 106 catch(Exception) 107 { 108 } 109 return cast(size_t)(value ^ (value >>> 32)); 110 } 111 112 override 113 bool opEquals(Object obj) { 114 // if (!(cast(SQLIdentifierExpr)(obj) !is null)) { 115 // return false; 116 // } 117 118 SQLIdentifierExpr other = cast(SQLIdentifierExpr) obj; 119 if(other is null) 120 return false; 121 return this.hashCode64() == other.hashCode64(); 122 } 123 124 override string toString() { 125 return this.name; 126 } 127 128 override SQLIdentifierExpr clone() { 129 SQLIdentifierExpr x = new SQLIdentifierExpr(this.name, _hashCode64); 130 x.resolvedColumn = resolvedColumn; 131 x.resolvedOwnerObject = resolvedOwnerObject; 132 return x; 133 } 134 135 SQLIdentifierExpr simplify() { 136 string normalized = SQLUtils.normalize(name); 137 if (normalized != name) { 138 return new SQLIdentifierExpr(normalized, _hashCode64); 139 } 140 return this; 141 } 142 143 string normalizedName() { 144 return SQLUtils.normalize(name); 145 } 146 147 SQLColumnDefinition getResolvedColumn() { 148 if ( cast(SQLColumnDefinition)resolvedColumn !is null) { 149 return cast(SQLColumnDefinition) resolvedColumn; 150 } 151 152 return null; 153 } 154 155 SQLObject getResolvedColumnObject() { 156 return resolvedColumn; 157 } 158 159 void setResolvedColumn(SQLColumnDefinition resolvedColumn) { 160 this.resolvedColumn = resolvedColumn; 161 } 162 163 SQLTableSource getResolvedTableSource() { 164 if (cast(SQLTableSource)resolvedOwnerObject !is null) { 165 return cast(SQLTableSource) resolvedOwnerObject; 166 } 167 168 return null; 169 } 170 171 void setResolvedTableSource(SQLTableSource resolvedTableSource) { 172 this.resolvedOwnerObject = resolvedTableSource; 173 } 174 175 SQLObject getResolvedOwnerObject() { 176 return resolvedOwnerObject; 177 } 178 179 void setResolvedOwnerObject(SQLObject resolvedOwnerObject) { 180 this.resolvedOwnerObject = resolvedOwnerObject; 181 } 182 183 SQLParameter getResolvedParameter() { 184 if (cast(SQLParameter)resolvedColumn !is null) { 185 return cast(SQLParameter) this.resolvedColumn; 186 } 187 return null; 188 } 189 190 void setResolvedParameter(SQLParameter resolvedParameter) { 191 this.resolvedColumn = resolvedParameter; 192 } 193 194 SQLDeclareItem getResolvedDeclareItem() { 195 if ( cast(SQLDeclareItem)resolvedColumn !is null) { 196 return cast(SQLDeclareItem) this.resolvedColumn; 197 } 198 return null; 199 } 200 201 void setResolvedDeclareItem(SQLDeclareItem resolvedDeclareItem) { 202 this.resolvedColumn = resolvedDeclareItem; 203 } 204 205 override SQLDataType computeDataType() { 206 SQLColumnDefinition resolvedColumn = getResolvedColumn(); 207 if (resolvedColumn !is null) { 208 return resolvedColumn.getDataType(); 209 } 210 211 if (resolvedOwnerObject !is null 212 && (cast(SQLSubqueryTableSource)resolvedOwnerObject !is null)) { 213 SQLSelect select = (cast(SQLSubqueryTableSource) resolvedOwnerObject).getSelect(); 214 SQLSelectQueryBlock queryBlock = select.getFirstQueryBlock(); 215 if (queryBlock is null) { 216 return null; 217 } 218 SQLSelectItem selectItem = queryBlock.findSelectItem(nameHashCode64()); 219 if (selectItem !is null) { 220 return selectItem.computeDataType(); 221 } 222 } 223 224 return null; 225 } 226 227 bool nameEquals(string name) { 228 return SQLUtils.nameEquals(this.name, name); 229 } 230 231 override 232 List!SQLObject getChildren() { 233 return Collections.emptyList!(SQLObject)(); 234 } 235 236 static bool matchIgnoreCase(SQLExpr expr, string name) { 237 // if (!(cast(SQLIdentifierExpr)(expr) !is null)) { 238 // return false; 239 // } 240 SQLIdentifierExpr ident = cast(SQLIdentifierExpr) expr; 241 if(ident is null) 242 return false; 243 return equalsIgnoreCase(name,ident.getName()); 244 } 245 }