001/* 002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Florent Guillaume 018 */ 019package org.nuxeo.ecm.core.query.sql.model; 020 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.List; 024import java.util.Map.Entry; 025 026import org.nuxeo.ecm.core.query.QueryParseException; 027 028/** 029 * Transforms a query into the same query, doing a copy in the process. 030 * <p> 031 * Can be used as a base class for more complex transformations. 032 * 033 * @since 9.10 034 */ 035public class IdentityQueryTransformer implements QueryTransformer { 036 037 @Override 038 public SQLQuery transform(SQLQuery node) { 039 SelectClause select = transform(node.select); 040 FromClause from = transform(node.from); 041 WhereClause where = transform(node.where); 042 GroupByClause groupBy = transform(node.groupBy); 043 HavingClause having = transform(node.having); 044 OrderByClause orderBy = transform(node.orderBy); 045 long limit = transformLimit(node.limit); 046 long offset = transformOffset(node.offset); 047 return new SQLQuery(select, from, where, groupBy, having, orderBy, limit, offset); 048 } 049 050 @Override 051 public SelectClause transform(SelectClause node) { 052 return new SelectClause(transform(node.elements), node.distinct); 053 } 054 055 @Override 056 public SelectList transform(SelectList node) { 057 SelectList list = new SelectList(); 058 for (Entry<String, Operand> es : node.entrySet()) { 059 list.put(es.getKey(), transform(es.getValue())); 060 } 061 return list; 062 } 063 064 @Override 065 public FromClause transform(FromClause node) { 066 return new FromClause(transform(node.elements)); 067 } 068 069 @Override 070 public FromList transform(FromList node) { 071 FromList list = new FromList(); 072 list.putAll(node); 073 return list; 074 } 075 076 @Override 077 public WhereClause transform(WhereClause node) { 078 return new WhereClause(transform(node.predicate)); 079 } 080 081 @Override 082 public GroupByClause transform(GroupByClause node) { 083 if (node == null) { 084 return null; 085 } 086 String[] elements = node.elements; 087 if (elements != null) { 088 return new GroupByClause(Arrays.asList(elements)); 089 } else { 090 return new GroupByClause(); 091 } 092 } 093 094 @Override 095 public HavingClause transform(HavingClause node) { 096 if (node == null) { 097 return null; 098 } 099 return new HavingClause(transform(node.predicate)); 100 } 101 102 @Override 103 public OrderByClause transform(OrderByClause node) { 104 if (node == null) { 105 return null; 106 } 107 return new OrderByClause(transform(node.elements)); 108 } 109 110 @Override 111 public OrderByList transform(OrderByList node) { 112 OrderByList list = new OrderByList(); 113 for (OrderByExpr value : node) { 114 list.add(transform(value)); 115 } 116 return list; 117 } 118 119 @Override 120 public OrderByExpr transform(OrderByExpr node) { 121 return new OrderByExpr(transform(node.reference), node.isDescending); 122 } 123 124 @Override 125 public long transformLimit(long limit) { 126 return limit; 127 } 128 129 @Override 130 public long transformOffset(long offset) { 131 return offset; 132 } 133 134 @Override 135 public Operand transform(Operand node) { 136 if (node instanceof Literal) { 137 return transform((Literal) node); 138 } else if (node instanceof LiteralList) { 139 return transform((LiteralList) node); 140 } else if (node instanceof Function) { 141 return transform((Function) node); 142 } else if (node instanceof MultiExpression) { 143 return transform((MultiExpression) node); 144 } else if (node instanceof Predicate) { 145 return transform((Predicate) node); 146 } else if (node instanceof Expression) { 147 return transform((Expression) node); 148 } else if (node instanceof Reference) { 149 return transform((Reference) node); 150 } else { 151 throw new QueryParseException("Unknown operand: " + node); 152 } 153 } 154 155 @Override 156 public Expression transform(Expression node) { 157 if (node instanceof Predicate) { 158 return transform((Predicate) node); 159 } 160 Expression expr = new Expression(transform(node.lvalue), transform(node.operator), transform(node.rvalue)); 161 expr.info = node.info; 162 return expr; 163 } 164 165 @Override 166 public Predicate transform(Predicate node) { 167 if (node instanceof MultiExpression) { 168 return transform((MultiExpression) node); 169 } 170 Predicate predicate = new Predicate(transform(node.lvalue), transform(node.operator), transform(node.rvalue)); 171 predicate.info = node.info; 172 return predicate; 173 } 174 175 @Override 176 public MultiExpression transform(MultiExpression node) { 177 List<Predicate> predicates = new ArrayList<>(node.predicates.size()); 178 for (Predicate predicate : node.predicates) { 179 predicates.add(transform(predicate)); 180 } 181 MultiExpression expr = new MultiExpression(transform(node.operator), predicates); 182 expr.info = node.info; 183 return expr; 184 } 185 186 @Override 187 public Operator transform(Operator node) { 188 return node; 189 } 190 191 @Override 192 public Reference transform(Reference node) { 193 Reference ref = new Reference(node.name, node.cast, node.esHint); 194 ref.info = node.info; 195 return ref; 196 } 197 198 @Override 199 public ReferenceList transform(ReferenceList node) { 200 ReferenceList list = new ReferenceList(); 201 for (Reference ref : node) { 202 list.add(transform(ref)); 203 } 204 return list; 205 } 206 207 @Override 208 public Operand transform(Function node) { 209 return new Function(node.name, transform(node.args)); 210 } 211 212 @Override 213 public OperandList transform(OperandList node) { 214 OperandList list = new OperandList(); 215 for (Operand oper : node) { 216 list.add(transform(oper)); 217 } 218 return list; 219 } 220 221 @Override 222 public Literal transform(Literal node) { 223 if (node instanceof BooleanLiteral) { 224 return transform((BooleanLiteral) node); 225 } else if (node instanceof DateLiteral) { 226 return transform((DateLiteral) node); 227 } else if (node instanceof DoubleLiteral) { 228 return transform((DoubleLiteral) node); 229 } else if (node instanceof IntegerLiteral) { 230 return transform((IntegerLiteral) node); 231 } else if (node instanceof StringLiteral) { 232 return transform((StringLiteral) node); 233 } else { 234 throw new QueryParseException("Unknown literal: " + node); 235 } 236 } 237 238 @Override 239 public LiteralList transform(LiteralList node) { 240 LiteralList list = new LiteralList(); 241 for (Literal lit : node) { 242 list.add(transform(lit)); 243 } 244 return list; 245 } 246 247 @Override 248 public Literal transform(BooleanLiteral node) { 249 return node; 250 } 251 252 @Override 253 public Literal transform(DateLiteral node) { 254 return node; 255 } 256 257 @Override 258 public Literal transform(DoubleLiteral node) { 259 return node; 260 } 261 262 @Override 263 public Literal transform(IntegerLiteral node) { 264 return node; 265 } 266 267 @Override 268 public Literal transform(StringLiteral node) { 269 return node; 270 } 271 272}