Search in sources :

Example 1 with IndexTextAndJsonValues

use of org.folio.cql2pgjson.model.IndexTextAndJsonValues in project raml-module-builder by folio-org.

the class CQL2PgJSON method indexNodeForForeignTable.

private String indexNodeForForeignTable(CQLTermNode node, Table targetTable, String[] foreignTarget) throws QueryValidationException {
    String foreignTableJsonb = targetTable.getTableName() + "." + JSONB_COLUMN_NAME;
    IndexTextAndJsonValues vals = new IndexTextAndJsonValues();
    vals.setIndexJson(SqlUtil.Cql2PgUtil.cqlNameAsSqlJson(foreignTableJsonb, foreignTarget[1]));
    vals.setIndexText(SqlUtil.Cql2PgUtil.cqlNameAsSqlText(foreignTableJsonb, foreignTarget[1]));
    CqlModifiers cqlModifiers = new CqlModifiers(node);
    String indexField = foreignTarget[1];
    return indexNode(indexField, targetTable, node, vals, cqlModifiers);
}
Also used : IndexTextAndJsonValues(org.folio.cql2pgjson.model.IndexTextAndJsonValues) CqlModifiers(org.folio.cql2pgjson.model.CqlModifiers)

Example 2 with IndexTextAndJsonValues

use of org.folio.cql2pgjson.model.IndexTextAndJsonValues in project raml-module-builder by folio-org.

the class CQL2PgJSON method toSql.

// suppress "reduce to one continue in for loop"
@SuppressWarnings("squid:S135")
private SqlSelect toSql(CQLSortNode node) throws QueryValidationException {
    StringBuilder order = new StringBuilder();
    String where = pg(node.getSubtree());
    boolean firstIndex = true;
    for (ModifierSet modifierSet : node.getSortIndexes()) {
        if (firstIndex) {
            firstIndex = false;
        } else {
            order.append(", ");
        }
        String desc = "";
        CqlModifiers modifiers = new CqlModifiers(modifierSet);
        if (modifiers.getCqlSort() == CqlSort.DESCENDING) {
            desc = " DESC";
        }
        // ASC not needed, it's Postgres' default
        String field = modifierSet.getBase();
        DbIndex dbIndex = dbIndexMap.computeIfAbsent(field, f -> DbSchemaUtils.getDbIndex(dbTable, f));
        if (dbIndex.isForeignKey() || "id".equals(field)) {
            order.append(field).append(desc);
            continue;
        }
        IndexTextAndJsonValues vals = getIndexTextAndJsonValues(field);
        // if sort field is marked explicitly as number type
        if (modifiers.getCqlTermFormat() == CqlTermFormat.NUMBER) {
            order.append(vals.getIndexJson()).append(desc);
            continue;
        }
        // We assume that a CREATE INDEX for this has been installed.
        order.append(wrapForLength(wrapInLowerUnaccent(vals.getIndexText(), modifiers))).append(desc).append(", ").append(wrapInLowerUnaccent(vals.getIndexText(), modifiers)).append(desc);
    }
    return new SqlSelect(where, order.toString());
}
Also used : CqlModifiers(org.folio.cql2pgjson.model.CqlModifiers) IndexTextAndJsonValues(org.folio.cql2pgjson.model.IndexTextAndJsonValues) SqlSelect(org.folio.cql2pgjson.model.SqlSelect) ModifierSet(org.z3950.zing.cql.ModifierSet) DbIndex(org.folio.cql2pgjson.model.DbIndex)

Example 3 with IndexTextAndJsonValues

use of org.folio.cql2pgjson.model.IndexTextAndJsonValues in project raml-module-builder by folio-org.

the class CQL2PgJSON method multiFieldProcessing.

private IndexTextAndJsonValues multiFieldProcessing(String index) {
    IndexTextAndJsonValues vals = new IndexTextAndJsonValues();
    // processing for case where index is prefixed with json field name
    for (String f : jsonFields) {
        if (index.startsWith(f + '.')) {
            String indexTermWithinField = index.substring(f.length() + 1);
            vals.setIndexJson(SqlUtil.Cql2PgUtil.cqlNameAsSqlJson(f, indexTermWithinField));
            vals.setIndexText(SqlUtil.Cql2PgUtil.cqlNameAsSqlText(f, indexTermWithinField));
            return vals;
        }
    }
    // if no json field name prefix is found, the default field name gets applied.
    String defaultJsonField = this.jsonFields.get(0);
    vals.setIndexJson(SqlUtil.Cql2PgUtil.cqlNameAsSqlJson(defaultJsonField, index));
    vals.setIndexText(SqlUtil.Cql2PgUtil.cqlNameAsSqlText(defaultJsonField, index));
    return vals;
}
Also used : IndexTextAndJsonValues(org.folio.cql2pgjson.model.IndexTextAndJsonValues)

Example 4 with IndexTextAndJsonValues

use of org.folio.cql2pgjson.model.IndexTextAndJsonValues in project raml-module-builder by folio-org.

the class CQL2PgJSON method arrayNode.

private String arrayNode(String index, CQLTermNode node, CqlModifiers modifiers, List<Modifier> relationModifiers, Index schemaIndex, IndexTextAndJsonValues incomingvals, Table targetTable) throws QueryValidationException {
    StringBuilder sqlAnd = new StringBuilder();
    StringBuilder sqlOr = new StringBuilder();
    // avoid recursion
    modifiers.setRelationModifiers(new LinkedList<>());
    for (Modifier relationModifier : relationModifiers) {
        final String modifierName = relationModifier.getType().substring(1);
        final String modifierValue = relationModifier.getValue();
        String foundModifier = lookupModifier(schemaIndex, modifierName);
        if (foundModifier == null) {
            throw new QueryValidationException("CQL: Unsupported relation modifier " + relationModifier.getType());
        }
        if (modifierValue == null) {
            if (sqlOr.length() == 0) {
                sqlOr.append("(");
            } else {
                sqlOr.append(" or ");
            }
            IndexTextAndJsonValues vals = new IndexTextAndJsonValues();
            vals.setIndexText(SqlUtil.Cql2PgUtil.cqlNameAsSqlText("t.c", foundModifier));
            sqlOr.append(indexNode(index, this.dbTable, node, vals, modifiers));
        } else {
            final String comparator = relationModifier.getComparison();
            if (!"=".equals(comparator)) {
                throw new QueryValidationException("CQL: Unsupported comparison for relation modifier " + relationModifier.getType());
            }
            sqlAnd.append(" and ");
            sqlAnd.append(queryByFt(SqlUtil.Cql2PgUtil.cqlNameAsSqlText("t.c", foundModifier), modifierValue, comparator, schemaIndex, targetTable));
        }
    }
    if (sqlOr.length() > 0) {
        sqlOr.append(")");
    } else {
        String modifiersSubfield = null;
        if (schemaIndex != null) {
            modifiersSubfield = schemaIndex.getArraySubfield();
        }
        if (modifiersSubfield == null) {
            throw new QueryValidationException("CQL: No arraySubfield defined for index " + index);
        }
        IndexTextAndJsonValues vals = new IndexTextAndJsonValues();
        vals.setIndexText(SqlUtil.Cql2PgUtil.cqlNameAsSqlText("t.c", modifiersSubfield));
        sqlOr.append(indexNode(index, this.dbTable, node, vals, modifiers));
    }
    return "id in (select t.id" + " from (select id as id, " + "             jsonb_array_elements(" + incomingvals.getIndexJson() + ") as c" + "      ) as t" + " where " + sqlOr.toString() + sqlAnd.toString() + ")";
}
Also used : IndexTextAndJsonValues(org.folio.cql2pgjson.model.IndexTextAndJsonValues) QueryValidationException(org.folio.cql2pgjson.exception.QueryValidationException) Modifier(org.z3950.zing.cql.Modifier)

Example 5 with IndexTextAndJsonValues

use of org.folio.cql2pgjson.model.IndexTextAndJsonValues in project raml-module-builder by folio-org.

the class CQL2PgJSON method index2sql.

/**
 * Create an SQL expression where index is applied to all matches.
 *
 * @param index index to use
 * @param node CQLTermNode to use
 *
 * @return SQL expression
 * @throws QueryValidationException
 */
private String index2sql(String index, CQLTermNode node) throws QueryValidationException {
    IndexTextAndJsonValues vals = getIndexTextAndJsonValues(index);
    CqlModifiers cqlModifiers = new CqlModifiers(node);
    return indexNode(index, this.dbTable, node, vals, cqlModifiers);
}
Also used : IndexTextAndJsonValues(org.folio.cql2pgjson.model.IndexTextAndJsonValues) CqlModifiers(org.folio.cql2pgjson.model.CqlModifiers)

Aggregations

IndexTextAndJsonValues (org.folio.cql2pgjson.model.IndexTextAndJsonValues)7 CqlModifiers (org.folio.cql2pgjson.model.CqlModifiers)4 QueryValidationException (org.folio.cql2pgjson.exception.QueryValidationException)2 DbIndex (org.folio.cql2pgjson.model.DbIndex)2 SqlSelect (org.folio.cql2pgjson.model.SqlSelect)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 List (java.util.List)1 Map (java.util.Map)1 Level (java.util.logging.Level)1 Logger (java.util.logging.Logger)1 Pattern (java.util.regex.Pattern)1 ObjectUtils (org.apache.commons.lang3.ObjectUtils)1 StringUtils (org.apache.commons.lang3.StringUtils)1 CQLFeatureUnsupportedException (org.folio.cql2pgjson.exception.CQLFeatureUnsupportedException)1 FieldException (org.folio.cql2pgjson.exception.FieldException)1 ServerChoiceIndexesException (org.folio.cql2pgjson.exception.ServerChoiceIndexesException)1