@Override protected <U extends IValue> Result<U> addTuple(TupleResult that) { // Note reversed args TupleResult left = that; TupleResult right = this; Type leftType = left.getType(); Type rightType = right.getType(); int leftArity = leftType.getArity(); int rightArity = rightType.getArity(); int newArity = leftArity + rightArity; Type fieldTypes[] = new Type[newArity]; String fieldNames[] = new String[newArity]; IValue fieldValues[] = new IValue[newArity]; boolean consistentLabels = true; for (int i = 0; i < leftArity; i++) { fieldTypes[i] = leftType.getFieldType(i); fieldNames[i] = leftType.getFieldName(i); fieldValues[i] = left.getValue().get(i); consistentLabels = fieldNames[i] != null; } for (int i = 0; i < rightArity; i++) { fieldTypes[leftArity + i] = rightType.getFieldType(i); fieldNames[leftArity + i] = rightType.getFieldName(i); fieldValues[leftArity + i] = right.getValue().get(i); consistentLabels = fieldNames[i] != null; if (consistentLabels) { for (int j = 0; j < leftArity; j++) { if (fieldNames[j].equals(fieldNames[i])) { // duplicate field name, so degenerate to unlabeled tuple consistentLabels = false; } } } } Type newTupleType; if (consistentLabels) { newTupleType = getTypeFactory().tupleType(fieldTypes, fieldNames); } else { newTupleType = getTypeFactory().tupleType(fieldTypes); } return makeResult(newTupleType, getValueFactory().tuple(fieldValues), ctx); }
public void write(IValue rel, ISourceLocation loc, IEvaluatorContext ctx) { OutputStream out = null; Type paramType = ctx.getCurrentEnvt().getTypeBindings().get(types.parameterType("T")); if (!paramType.isRelation() && !paramType.isListRelation()) { throw RuntimeExceptionFactory.illegalTypeArgument( "A relation type is required instead of " + paramType, ctx.getCurrentAST(), ctx.getStackTrace()); } try { boolean isListRel = rel instanceof IList; out = ctx.getResolverRegistry().getOutputStream(loc.getURI(), false); ISet irel = null; IList lrel = null; if (isListRel) { lrel = (IList) rel; } else { irel = (ISet) rel; } int nfields = isListRel ? lrel.asRelation().arity() : irel.asRelation().arity(); if (header) { for (int i = 0; i < nfields; i++) { if (i > 0) out.write(separator); String label = paramType.getFieldName(i); if (label == null || label.isEmpty()) label = "field" + i; writeString(out, label); } out.write('\n'); } String separatorAsString = new String(Character.toChars(separator)); for (IValue v : (isListRel ? lrel : irel)) { ITuple tup = (ITuple) v; int sep = 0; for (IValue w : tup) { if (sep == 0) sep = separator; else out.write(sep); if (w.getType().isString()) { String s = ((IString) w).getValue(); if (s.contains(separatorAsString) || s.contains("\n") || s.contains("\r") || s.contains("\"")) { s = s.replaceAll("\"", "\"\""); out.write('"'); writeString(out, s); out.write('"'); } else writeString(out, s); } else { writeString(out, w.toString()); } } out.write('\n'); } out.flush(); out.close(); } catch (IOException e) { throw RuntimeExceptionFactory.io(values.string(e.getMessage()), null, null); } finally { if (out != null) { try { out.flush(); out.close(); } catch (IOException ioex) { throw RuntimeExceptionFactory.io(values.string(ioex.getMessage()), null, null); } } } }