private void checkRecord(Type eltType, Record record, IEvaluatorContext ctx) { // TODO: not all inconsistencies are detected yet // probably because absent values get type void // but are nevertheless initialized eventually // to 0, false, or "". if (record.getType().isSubtypeOf(eltType)) { return; } if (eltType.isTuple()) { int expectedArity = eltType.getArity(); int actualArity = record.getType().getArity(); if (expectedArity == actualArity) { return; } throw RuntimeExceptionFactory.illegalTypeArgument( "Arities of actual type and requested type are different (" + actualArity + " vs " + expectedArity + ")", ctx.getCurrentAST(), ctx.getStackTrace()); } throw RuntimeExceptionFactory.illegalTypeArgument( "Invalid tuple " + record + " for requested field " + eltType, ctx.getCurrentAST(), ctx.getStackTrace()); }
public IValue buildCollection(Type type, List<Record> records, IEvaluatorContext ctx) { IWriter writer; while (type.isAliased()) { type = type.getAliased(); } if (type.isList()) { writer = values.listWriter(type.getElementType()); } else if (type.isRelation()) { writer = values.relationWriter(type.getElementType()); } else { throw RuntimeExceptionFactory.illegalTypeArgument( "Invalid result type for CSV reading: " + type, ctx.getCurrentAST(), ctx.getStackTrace()); } // reverse traversal so that the order in case of ListWriter is correct // (IWriter only supports inserts at the front). Type eltType = type.getElementType(); for (int i = records.size() - 1; i >= 0; i--) { Record record = records.get(i); checkRecord(eltType, record, ctx); writer.insert(record.getTuple(eltType)); } return writer.done(); }
private Type inferType(List<Record> records, IEvaluatorContext ctx) throws IOException { String[] labels = null; if (header) { labels = extractLabels(records.remove(0)); } Type[] fieldTypes = null; for (Record ri : records) { List<Type> ftypes = ri.getFieldTypes(); if (fieldTypes == null) { fieldTypes = new Type[ftypes.size()]; Arrays.fill(fieldTypes, types.voidType()); } else if (ftypes.size() != fieldTypes.length) { // We assume all records in the CSV file to have the same arity. throw RuntimeExceptionFactory.illegalArgument( // "Inconsistent tuple in CSV expected " + fieldTypes.length + " but was " + // ftypes.size(), ctx.getCurrentAST(), ctx.getStackTrace()); } for (int i = 0; i < ftypes.size(); i++) { fieldTypes[i] = fieldTypes[i].lub(ftypes.get(i)); if (fieldTypes[i].isTop()) { fieldTypes[i] = types.stringType(); } } } if (labels == null) { labels = makeUpLabels(fieldTypes.length); } return types.setType(types.tupleType(fieldTypes, labels)); }
private String[] extractLabels(Record record) { String[] labels = new String[record.getWidth()]; int i = 0; for (String label : record) { label = normalizeLabel(label, i); labels[i] = label; i++; } return labels; }