1 module hunt.sql.ast.expr.SQLPropertyExpr; 2 import hunt.sql.ast.SQLExprImpl; 3 import hunt.sql.ast.SQLName; 4 import hunt.sql.ast.SQLExpr; 5 import hunt.sql.ast.SQLObject; 6 import hunt.sql.ast.statement.SQLColumnDefinition; 7 import hunt.collection; 8 import hunt.sql.visitor.SQLASTVisitor; 9 import hunt.sql.ast.statement.SQLTableSource; 10 import hunt.sql.ast.statement.SQLCreateProcedureStatement; 11 import hunt.sql.ast.SQLDataType; 12 import hunt.sql.ast.statement.SQLSelectItem; 13 import hunt.sql.ast.statement.SQLSelect; 14 import hunt.sql.ast.statement.SQLSelectQueryBlock; 15 import hunt.sql.ast.expr.SQLIdentifierExpr; 16 import hunt.sql.util.FnvHash; 17 import hunt.String; 18 import hunt.sql.SQLUtils; 19 import hunt.sql.ast.statement.SQLSubqueryTableSource; 20 import hunt.text; 21 22 public class SQLPropertyExpr : SQLExprImpl , SQLName { 23 private SQLExpr owner; 24 private string name; 25 26 protected long nameHashCod64; 27 protected long _hashCode64; 28 29 protected SQLColumnDefinition resolvedColumn; 30 protected SQLObject resolvedOwnerObject; 31 32 public this(string owner, string name){ 33 this(new SQLIdentifierExpr(owner), name); 34 } 35 36 public this(SQLExpr owner, string name){ 37 setOwner(owner); 38 this.name = name; 39 } 40 41 public this(SQLExpr owner, string name, long nameHashCod64){ 42 setOwner(owner); 43 this.name = name; 44 this.nameHashCod64 = nameHashCod64; 45 } 46 47 public this(){ 48 49 } 50 51 public string getSimpleName() { 52 return name; 53 } 54 55 public SQLExpr getOwner() { 56 return this.owner; 57 } 58 59 public string getOwnernName() { 60 if ( cast(SQLName)owner !is null) { 61 return (cast(Object) owner).toString(); 62 } 63 64 return null; 65 } 66 67 public void setOwner(SQLExpr owner) { 68 if (owner !is null) { 69 owner.setParent(this); 70 } 71 72 if ( cast(SQLPropertyExpr)parent !is null) { 73 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) parent; 74 propertyExpr.computeHashCode64(); 75 } 76 77 this.owner = owner; 78 this._hashCode64 = 0; 79 } 80 81 public void computeHashCode64() { 82 long hash; 83 if ( cast(SQLName)owner !is null) { 84 hash = (cast(SQLName) owner).hashCode64(); 85 86 hash ^= '.'; 87 hash *= FnvHash.PRIME; 88 } else if (owner is null){ 89 hash = FnvHash.BASIC; 90 } else { 91 hash = FnvHash.fnv1a_64_lower((cast(Object)owner).toString()); 92 93 hash ^= '.'; 94 hash *= FnvHash.PRIME; 95 } 96 hash = FnvHash.hashCode64(hash, name); 97 _hashCode64 = hash; 98 } 99 100 public void setOwner(string owner) { 101 this.setOwner(new SQLIdentifierExpr(owner)); 102 } 103 104 public string getName() { 105 return this.name; 106 } 107 108 public void setName(string name) { 109 this.name = name; 110 this._hashCode64 = 0; 111 this.nameHashCod64 = 0; 112 113 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) parent; 114 if (propertyExpr !is null) { 115 propertyExpr.computeHashCode64(); 116 } 117 } 118 119 override public void output(StringBuilder buf) { 120 import hunt.logging; 121 SQLIdentifierExpr qe = cast(SQLIdentifierExpr)this.owner; 122 this.owner.output(buf); 123 buf.append("."); 124 buf.append(this.name); 125 } 126 127 override protected void accept0(SQLASTVisitor visitor) { 128 if (visitor.visit(this)) { 129 acceptChild(visitor, this.owner); 130 } 131 132 visitor.endVisit(this); 133 } 134 135 override 136 public List!SQLObject getChildren() { 137 return Collections.singletonList!SQLObject(this.owner); 138 } 139 140 override 141 public size_t toHash() @trusted nothrow { 142 long hash; 143 try{ 144 hash= hashCode64(); 145 }catch(Exception){} 146 147 return cast(size_t)(hash ^ (hash >>> 32)); 148 } 149 150 public long hashCode64() { 151 if (_hashCode64 == 0) { 152 computeHashCode64(); 153 } 154 155 return _hashCode64; 156 } 157 158 override 159 public bool opEquals(Object obj) { 160 if (this is obj) { 161 return true; 162 } 163 if (obj is null) { 164 return false; 165 } 166 // if (!(cast(SQLPropertyExpr)(obj) !is null)) { 167 // return false; 168 // } 169 SQLPropertyExpr other = cast(SQLPropertyExpr) obj; 170 if(other is null) 171 return false; 172 173 if (name is null) { 174 if (other.name !is null) { 175 return false; 176 } 177 } else if (name != (other.name)) { 178 return false; 179 } 180 if (owner is null) { 181 if (other.owner !is null) { 182 return false; 183 } 184 } else if (owner != (other.owner)) { 185 return false; 186 } 187 return true; 188 } 189 190 // override bool opEquals(Object o) { 191 // if (o is this) 192 // return true; 193 194 // return opEquals(o); 195 // } 196 197 // override size_t toHash() @trusted nothrow { 198 // return hashCode(); 199 // } 200 201 override public SQLPropertyExpr clone() { 202 SQLExpr owner_x = null; 203 if (owner !is null) { 204 owner_x = owner.clone(); 205 } 206 207 SQLPropertyExpr x = new SQLPropertyExpr(owner_x, name, nameHashCod64); 208 209 x._hashCode64 = _hashCode64; 210 x.resolvedColumn = resolvedColumn; 211 x.resolvedOwnerObject = resolvedOwnerObject; 212 213 return x; 214 } 215 216 public bool matchOwner(string alias_p) { 217 auto obj = cast(SQLIdentifierExpr) owner; 218 if (obj !is null) { 219 return equalsIgnoreCase(obj.getName(),alias_p); 220 } 221 222 return false; 223 } 224 225 public long nameHashCode64() { 226 if (nameHashCod64 == 0 227 && name !is null) { 228 nameHashCod64 = FnvHash.hashCode64(name); 229 } 230 return nameHashCod64; 231 } 232 233 public string normalizedName() { 234 235 string ownerName; 236 if ( cast(SQLIdentifierExpr)owner !is null) { 237 ownerName = (cast(SQLIdentifierExpr) owner).normalizedName(); 238 } else if ( cast(SQLPropertyExpr)owner !is null) { 239 ownerName = (cast(SQLPropertyExpr) owner).normalizedName(); 240 } else { 241 ownerName = (cast(Object)owner).toString(); 242 } 243 244 return ownerName ~ '.' ~ SQLUtils.normalize(name); 245 } 246 247 public SQLColumnDefinition getResolvedColumn() { 248 return resolvedColumn; 249 } 250 251 public void setResolvedColumn(SQLColumnDefinition resolvedColumn) { 252 this.resolvedColumn = resolvedColumn; 253 } 254 255 public SQLTableSource getResolvedTableSource() { 256 if ( cast(SQLTableSource)resolvedOwnerObject !is null) { 257 return cast(SQLTableSource) resolvedOwnerObject; 258 } 259 260 return null; 261 } 262 263 public void setResolvedTableSource(SQLTableSource resolvedTableSource) { 264 this.resolvedOwnerObject = resolvedTableSource; 265 } 266 267 public void setResolvedProcedure(SQLCreateProcedureStatement stmt) { 268 this.resolvedOwnerObject = stmt; 269 } 270 271 public void setResolvedOwnerObject(SQLObject resolvedOwnerObject) { 272 this.resolvedOwnerObject = resolvedOwnerObject; 273 } 274 275 public SQLCreateProcedureStatement getResolvedProcudure() { 276 // if (cast(SQLCreateProcedureStatement)(this.resolvedOwnerObject) !is null) { 277 // return (SQLCreateProcedureStatement) this.resolvedOwnerObject; 278 // } 279 280 return cast(SQLCreateProcedureStatement) this.resolvedOwnerObject; 281 } 282 283 public SQLObject getResolvedOwnerObject() { 284 return resolvedOwnerObject; 285 } 286 287 override public SQLDataType computeDataType() { 288 if (resolvedColumn !is null) { 289 return resolvedColumn.getDataType(); 290 } 291 292 if (resolvedOwnerObject !is null 293 && cast(SQLSubqueryTableSource)resolvedOwnerObject !is null) { 294 SQLSelect select = (cast(SQLSubqueryTableSource) resolvedOwnerObject).getSelect(); 295 SQLSelectQueryBlock queryBlock = select.getFirstQueryBlock(); 296 if (queryBlock is null) { 297 return null; 298 } 299 SQLSelectItem selectItem = queryBlock.findSelectItem(nameHashCode64()); 300 if (selectItem !is null) { 301 return selectItem.computeDataType(); 302 } 303 } 304 305 return null; 306 } 307 308 public bool nameEquals(string name) { 309 return SQLUtils.nameEquals(this.name, name); 310 } 311 312 public SQLPropertyExpr simplify() { 313 string normalizedName = SQLUtils.normalize(name); 314 SQLExpr normalizedOwner = this.owner; 315 if ( cast(SQLIdentifierExpr)normalizedOwner !is null) { 316 normalizedOwner = (cast(SQLIdentifierExpr) normalizedOwner).simplify(); 317 } 318 319 if (normalizedName != name || normalizedOwner != owner) { 320 return new SQLPropertyExpr(normalizedOwner, normalizedName, _hashCode64); 321 } 322 323 return this; 324 } 325 326 override public string toString() { 327 if (owner is null) { 328 return this.name; 329 } 330 331 return (cast(Object)owner).toString() ~ '.' ~ name; 332 } 333 }