Search in sources :

Example 6 with CQLTermNode

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 + ")";
}
Also used : CQLTermNode(org.z3950.zing.cql.CQLTermNode)

Example 7 with CQLTermNode

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;
}
Also used : CQLAndNode(org.z3950.zing.cql.CQLAndNode) CQLNotNode(org.z3950.zing.cql.CQLNotNode) CQLProxNode(org.z3950.zing.cql.CQLProxNode) Modifier(org.z3950.zing.cql.Modifier) CQLNode(org.z3950.zing.cql.CQLNode) ModifierSet(org.z3950.zing.cql.ModifierSet) CQLOrNode(org.z3950.zing.cql.CQLOrNode)

Example 8 with CQLTermNode

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());
    }
}
Also used : ModifierSet(org.z3950.zing.cql.ModifierSet) SqlSelect(org.folio.cql2pgjson.model.SqlSelect) Cql2SqlUtil(org.folio.cql2pgjson.util.Cql2SqlUtil) CqlCase(org.folio.cql2pgjson.model.CqlCase) CQLTermNode(org.z3950.zing.cql.CQLTermNode) HashMap(java.util.HashMap) DbIndex(org.folio.cql2pgjson.model.DbIndex) CQLOrNode(org.z3950.zing.cql.CQLOrNode) StringUtils(org.apache.commons.lang3.StringUtils) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) CqlTermFormat(org.folio.cql2pgjson.model.CqlTermFormat) Index(org.folio.dbschema.Index) ObjectMapperTool(org.folio.dbschema.ObjectMapperTool) ObjectUtils(org.apache.commons.lang3.ObjectUtils) CqlSort(org.folio.cql2pgjson.model.CqlSort) DbFkInfo(org.folio.cql2pgjson.model.DbFkInfo) Map(java.util.Map) QueryValidationException(org.folio.cql2pgjson.exception.QueryValidationException) CQLParseException(org.z3950.zing.cql.CQLParseException) Schema(org.folio.dbschema.Schema) Table(org.folio.dbschema.Table) LinkedList(java.util.LinkedList) CQLFeatureUnsupportedException(org.folio.cql2pgjson.exception.CQLFeatureUnsupportedException) CQLSortNode(org.z3950.zing.cql.CQLSortNode) Modifier(org.z3950.zing.cql.Modifier) CQLBooleanNode(org.z3950.zing.cql.CQLBooleanNode) IndexTextAndJsonValues(org.folio.cql2pgjson.model.IndexTextAndJsonValues) SqlUtil(org.folio.dbschema.util.SqlUtil) IOException(java.io.IOException) CqlAccents(org.folio.cql2pgjson.model.CqlAccents) DbSchemaUtils(org.folio.cql2pgjson.util.DbSchemaUtils) Logger(java.util.logging.Logger) FieldException(org.folio.cql2pgjson.exception.FieldException) CqlModifiers(org.folio.cql2pgjson.model.CqlModifiers) List(java.util.List) CQLAndNode(org.z3950.zing.cql.CQLAndNode) CQLParser(org.z3950.zing.cql.CQLParser) ServerChoiceIndexesException(org.folio.cql2pgjson.exception.ServerChoiceIndexesException) ResourceUtil(org.folio.util.ResourceUtil) Pattern(java.util.regex.Pattern) CQLNode(org.z3950.zing.cql.CQLNode) Collections(java.util.Collections) CQLNotNode(org.z3950.zing.cql.CQLNotNode) DbIndex(org.folio.cql2pgjson.model.DbIndex) CQLFeatureUnsupportedException(org.folio.cql2pgjson.exception.CQLFeatureUnsupportedException)

Example 9 with CQLTermNode

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;
}
Also used : DbIndex(org.folio.cql2pgjson.model.DbIndex) Index(org.folio.dbschema.Index) Modifier(org.z3950.zing.cql.Modifier) CQLFeatureUnsupportedException(org.folio.cql2pgjson.exception.CQLFeatureUnsupportedException)

Aggregations

CQLNode (org.z3950.zing.cql.CQLNode)5 Modifier (org.z3950.zing.cql.Modifier)5 CQLTermNode (org.z3950.zing.cql.CQLTermNode)4 DbIndex (org.folio.cql2pgjson.model.DbIndex)3 Index (org.folio.dbschema.Index)3 ModifierSet (org.z3950.zing.cql.ModifierSet)3 CQLFeatureUnsupportedException (org.folio.cql2pgjson.exception.CQLFeatureUnsupportedException)2 QueryValidationException (org.folio.cql2pgjson.exception.QueryValidationException)2 IndexTextAndJsonValues (org.folio.cql2pgjson.model.IndexTextAndJsonValues)2 CQLAndNode (org.z3950.zing.cql.CQLAndNode)2 CQLBooleanNode (org.z3950.zing.cql.CQLBooleanNode)2 CQLNotNode (org.z3950.zing.cql.CQLNotNode)2 CQLOrNode (org.z3950.zing.cql.CQLOrNode)2 CQLParser (org.z3950.zing.cql.CQLParser)2 CQLRelation (org.z3950.zing.cql.CQLRelation)2 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1