use of org.z3950.zing.cql.CQLTermNode in project raml-module-builder by folio-org.
the class CQL2PgJSON method pg.
private String pg(CQLBooleanNode node) throws QueryValidationException {
String operator = sqlOperator(node);
String isNotTrue = "";
// typed in anything: title=* OR contributors*= OR identifier=*
if ("OR".equals(operator) && node.getRightOperand().getClass() == CQLTermNode.class) {
CQLTermNode r = (CQLTermNode) (node.getRightOperand());
if ("*".equals(r.getTerm()) && "=".equals(r.getRelation().getBase())) {
logger.log(Level.FINE, "pgFT(): Simplifying =* OR =* ");
return pg(node.getLeftOperand());
}
}
if ("AND NOT".equals(operator)) {
operator = "AND (";
isNotTrue = ") IS NOT TRUE";
// NOT TRUE is (FALSE or NULL) to catch the NULL case when the field does not exist.
// This completely inverts the right operand.
}
return "(" + pg(node.getLeftOperand()) + ") " + operator + " (" + pg(node.getRightOperand()) + isNotTrue + ")";
}
use of org.z3950.zing.cql.CQLTermNode in project okapi by folio-org.
the class CQLUtil method reduceBoolean.
private static CQLNode reduceBoolean(CQLBooleanNode n1, CQLTermNode tn, Comparator<CQLTermNode> cmp) {
CQLNode n2 = null;
CQLNode left = reducer(n1.getLeftOperand(), tn, cmp);
CQLNode right = reducer(n1.getRightOperand(), tn, cmp);
ModifierSet mSet = new ModifierSet(n1.getOperator().toString().toLowerCase());
List<Modifier> mods = n1.getModifiers();
for (Modifier m : mods) {
mSet.addModifier(m.getType(), m.getComparison(), m.getValue());
}
if (left == null) {
n2 = right;
} else if (right == null) {
n2 = left;
}
switch(n1.getOperator()) {
case AND:
if (left != null && right != null) {
n2 = new CQLAndNode(left, right, mSet);
}
break;
case OR:
if (left != null && right != null) {
n2 = new CQLOrNode(left, right, mSet);
}
break;
case NOT:
if (left != null && right != null) {
n2 = new CQLNotNode(left, right, mSet);
}
break;
case PROX:
if (left != null && right != null) {
n2 = new CQLProxNode(left, right, mSet);
}
break;
}
return n2;
}
use of org.z3950.zing.cql.CQLTermNode in project raml-module-builder by folio-org.
the class CQL2PgJSON method indexNode.
private String indexNode(String index, Table targetTable, CQLTermNode node, IndexTextAndJsonValues vals, CqlModifiers modifiers) throws QueryValidationException {
// primary key
if ("id".equals(index)) {
return pgId(node, index);
}
DbIndex dbIndex;
if (targetTable == null || dbTable.equals(targetTable)) {
dbIndex = dbIndexMap.computeIfAbsent(index, i -> DbSchemaUtils.getDbIndex(dbTable, index));
} else {
// foreign table
dbIndex = dbIndexMap.computeIfAbsent(vals.getIndexJson(), i -> DbSchemaUtils.getDbIndex(targetTable, index));
}
if (dbIndex.isForeignKey()) {
return pgId(node, index);
}
String comparator = node.getRelation().getBase().toLowerCase();
switch(comparator) {
case "=":
if (CqlTermFormat.NUMBER == modifiers.getCqlTermFormat()) {
return queryBySql(dbIndex, vals, node, comparator, modifiers);
} else {
return queryByFt(index, dbIndex, vals, node, comparator, modifiers, targetTable);
}
case "adj":
case "all":
case "any":
return queryByFt(index, dbIndex, vals, node, comparator, modifiers, targetTable);
case "==":
case "<>":
if (CqlTermFormat.STRING == modifiers.getCqlTermFormat()) {
return queryByLike(index, dbIndex, vals, node, comparator, modifiers, targetTable);
} else {
return queryBySql(dbIndex, vals, node, comparator, modifiers);
}
case "<":
case ">":
case "<=":
case ">=":
return queryBySql(dbIndex, vals, node, comparator, modifiers);
default:
throw new CQLFeatureUnsupportedException("Relation " + comparator + " not implemented yet: " + node.toString());
}
}
use of org.z3950.zing.cql.CQLTermNode in project raml-module-builder by folio-org.
the class CQL2PgJSON method queryByFt.
/**
* Create an SQL expression using Full Text query syntax.
*
* @param hasIndex
* @param vals
* @param node
* @param comparator
* @param modifiers
* @return
* @throws QueryValidationException
*/
private String queryByFt(String index, DbIndex dbIndex, IndexTextAndJsonValues vals, CQLTermNode node, String comparator, CqlModifiers modifiers, Table targetTable) throws QueryValidationException {
final String indexText = vals.getIndexText();
if (CqlAccents.RESPECT_ACCENTS == modifiers.getCqlAccents()) {
logger.log(Level.WARNING, "Ignoring /respectAccents modifier for FT search {0}", indexText);
}
if (CqlCase.RESPECT_CASE == modifiers.getCqlCase()) {
logger.log(Level.WARNING, "Ignoring /respectCase modifier for FT search {0}", indexText);
}
// Clean the term. Remove stand-alone ' *', not valid word.
String term = node.getTerm().replaceAll(" +\\*", "").trim();
Index schemaIndex = null;
if (targetTable != null) {
schemaIndex = DbSchemaUtils.getIndex(index, targetTable.getFullTextIndex());
}
String sql = queryByFt(indexText, term, comparator, schemaIndex, targetTable);
// array modifier
List<Modifier> relationModifiers = modifiers.getRelationModifiers();
if (!relationModifiers.isEmpty()) {
sql += " AND " + arrayNode(index, node, modifiers, relationModifiers, schemaIndex, vals, targetTable);
}
if (schemaIndex != null && schemaIndex.isCaseSensitive()) {
throw new CQLFeatureUnsupportedException("full text index does not support case sensitive: " + index);
}
if (!dbIndex.hasFullTextIndex() && !"true".equals(sql)) {
String s = String.format("%s, CQL >>> SQL: %s >>> %s", indexText, node.toCQL(), sql);
logger.log(Level.WARNING, "Doing FT search without index for {0}", s);
}
return sql;
}
Aggregations