[m-dev.] diff: fix Aditi indexing

Simon Taylor stayl at cs.mu.OZ.AU
Mon Mar 13 16:25:25 AEDT 2000


Estimated hours taken: 3

Fix some bugs in the optimization of indexed and sort joins.

compiler/rl_out.pp:
compiler/rl.m:
compiler/rl_dump.m:
compiler/rl_block_opt.m:
compiler/rl_stream.m:
compiler/rl_sort.m:
	Avoid adding indexes to base relations during queries.
	Change the code generated for an add_index instruction
	to first test whether the input relation is a base
	relation. If it is, the relation must be copied -- queries
	should never modify base relations.

	The add_index instruction now takes an input and returns
	an output, rather than just modifying its argument.

compiler/rl_sort.m:
	Fix the merging of sort and index information -- the code
	was erroneously finding that some relations were definitely
	sorted when they were only sorted on some of the branches leading
	into a block.

	Don't treat indexed relations as sorted when attempting
	to generate a sort-merge join -- if a relation is indexed
	an indexed join should be used.

compiler/rl_code.m:
	Add a rl_PROC_is_permanent bytecode to test whether
	a relation variable refers to a permanent relation.

	Increment the version number.


Index: rl.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl.m,v
retrieving revision 1.10
diff -u -u -r1.10 rl.m
--- rl.m	2000/03/01 01:04:46	1.10
+++ rl.m	2000/03/10 03:57:37
@@ -230,7 +230,10 @@
 		% input to the output, otherwise make the output a reference
 		% to the input. To introduce this, the compiler must know that
 		% there are no later references in the code to the input
-		% relation.
+		% relation. Base relations and named temporaries are always
+		% copied, because they have an implicit reference in the
+		% database's `relation name -> relation contents' mapping. 
+		%
 		% Make sure the output has the given set of indexes, even
 		% if it isn't copied.
 		make_unique(
@@ -268,10 +271,20 @@
 						% accumulator for each tuple.
 		)	
 	;
-		% Make sure the relation has the given index.
+		% Assign the input relation to the output, ensuring
+		% that the output has the appropriate indexes.
+		% If the input relation is a base relation, this will
+		% copy the input to the output. This sounds expensive,
+		% but currently in all cases where an index is added
+		% to something that might be a base relation, a copy
+		% needs to be made anyway because the relation is
+		% destructively updated by a uniondiff operation --
+		% all that will happen is that the make_unique instruction
+		% later will not need to make a copy.
+		%
 		% We don't include a remove_index operation because it
 		% would be very expensive and probably not very useful.
-		add_index(output_rel)
+		add_index(output_rel, relation_id)
 	;
 		% Empty a relation. This will be expensive for permanent
 		% relations due to logging.
@@ -669,7 +682,8 @@
 rl__instr_relations(init(output_rel(Rel, _)) - _, [], [Rel]).
 rl__instr_relations(insert_tuple(output_rel(Output, _), Input, _) - _,
 		[Input], [Output]).
-rl__instr_relations(add_index(output_rel(Rel, _)) - _, [Rel], [Rel]).
+rl__instr_relations(add_index(output_rel(Output, _), Input) - _,
+		[Input], [Output]).
 rl__instr_relations(clear(Rel) - _, [], [Rel]).
 rl__instr_relations(unset(Rel) - _, [], [Rel]).
 rl__instr_relations(label(_) - _, [], []).
Index: rl_block_opt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_block_opt.m,v
retrieving revision 1.6
diff -u -u -r1.6 rl_block_opt.m
--- rl_block_opt.m	2000/03/01 01:04:48	1.6
+++ rl_block_opt.m	2000/03/10 06:21:10
@@ -186,9 +186,10 @@
 	rl_block_opt__add_dag_node([Output], [InputNode],
 		aggregate(InputNode, Initial, Update), _).
 
-rl_block_opt__build_dag(add_index(output_rel(Rel, Index)) - _) -->
-	rl_block_opt__lookup_relation(Rel, RelNode),
-	rl_block_opt__add_index_to_node(RelNode, Index).
+rl_block_opt__build_dag(
+		add_index(Output, Input) - _) -->
+	rl_block_opt__lookup_relation(Input, InputNode),
+	rl_block_opt__set_output_rel_id(Output, InputNode).
 
 rl_block_opt__build_dag(clear(_) - _) -->
 	{ error("rl_block_opt__build_dag: clear") }.
@@ -1306,7 +1307,7 @@
 	{ OutputNode = output_node(Schema, Index, AllOutputs0) },
 	{ set__intersect(AllOutputs0, NonLocalRels, NonLocalOutputs0) },
 	{ Instr = input(InputRel1) ->
-		% Don't assigning the input relation to itself. 
+		% Don't assign the input relation to itself. 
 		set__delete(NonLocalOutputs0, InputRel1, NonLocalOutputs)
 	;
 		NonLocalOutputs = NonLocalOutputs0
@@ -1460,15 +1461,13 @@
 	{ OutputRel = output_rel(Output, Indexes) },
 
 	{ Indexes = [] ->
-		IndexInstrs = []
-	;
-		IndexInstrs = [add_index(OutputRel) - ""]
-	},
-
-	{ Output = Input ->
-		Instrs = IndexInstrs
+		( Output = Input ->
+			Instrs = []
+		;
+			Instrs = [ref(Output, Input) - ""]
+		)
 	;
-		Instrs = [ref(Output, Input) - "" | IndexInstrs]
+		Instrs = [add_index(OutputRel, Input) - ""]
 	}.
 
 %-----------------------------------------------------------------------------%
Index: rl_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_code.m,v
retrieving revision 1.10
diff -u -u -r1.10 rl_code.m
--- rl_code.m	2000/03/01 01:04:49	1.10
+++ rl_code.m	2000/03/13 03:33:54
@@ -5,7 +5,7 @@
 %-----------------------------------------------------------------------------%
 % Do not edit - this file was automatically generated by
 % $ADITI_ROOT/src/rosi/create_rl_code_m.
-% Created Mon Feb 28 10:57:44 2000
+% Created Mon Mar 13 14:33:54 2000
 
 %-----------------------------------------------------------------------------%
 :- module rl_code.
@@ -345,6 +345,7 @@
 	;	rl_PROC_notempty
 	;	rl_PROC_empty
 	;	rl_PROC_one_reference(int32)
+	;	rl_PROC_is_permanent(int32)
 	;	rl_PROC_has_index(int32,int32)
 	;	rl_PROC_and
 	;	rl_PROC_or
@@ -1459,268 +1460,272 @@
 	int16_to_bytecode(282, I282Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	list__condense([I282Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_PROC_has_index(X0int32,X1aString),	 Splits) :-
+bytecode_to_intlist(rl_PROC_is_permanent(X0int32),	 Splits) :-
 	int16_to_bytecode(283, I283Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
+	list__condense([I283Codes,X0int32Codes], Splits).
+bytecode_to_intlist(rl_PROC_has_index(X0int32,X1aString),	 Splits) :-
+	int16_to_bytecode(284, I284Codes),
+	int32_to_bytecode(X0int32, X0int32Codes),
 	int32_to_bytecode(X1aString, X1aStringCodes),
-	list__condense([I283Codes,X0int32Codes,X1aStringCodes], Splits).
+	list__condense([I284Codes,X0int32Codes,X1aStringCodes], Splits).
 bytecode_to_intlist(rl_PROC_and,	 Splits) :-
-	int16_to_bytecode(284, I284Codes),
-	list__condense([I284Codes], Splits).
-bytecode_to_intlist(rl_PROC_or,	 Splits) :-
 	int16_to_bytecode(285, I285Codes),
 	list__condense([I285Codes], Splits).
-bytecode_to_intlist(rl_PROC_not,	 Splits) :-
+bytecode_to_intlist(rl_PROC_or,	 Splits) :-
 	int16_to_bytecode(286, I286Codes),
 	list__condense([I286Codes], Splits).
-bytecode_to_intlist(rl_PROC_stream,	 Splits) :-
+bytecode_to_intlist(rl_PROC_not,	 Splits) :-
 	int16_to_bytecode(287, I287Codes),
 	list__condense([I287Codes], Splits).
-bytecode_to_intlist(rl_PROC_stream_end,	 Splits) :-
+bytecode_to_intlist(rl_PROC_stream,	 Splits) :-
 	int16_to_bytecode(288, I288Codes),
 	list__condense([I288Codes], Splits).
-bytecode_to_intlist(rl_PROC_stream_list_cons,	 Splits) :-
+bytecode_to_intlist(rl_PROC_stream_end,	 Splits) :-
 	int16_to_bytecode(289, I289Codes),
 	list__condense([I289Codes], Splits).
-bytecode_to_intlist(rl_PROC_stream_list_nil,	 Splits) :-
+bytecode_to_intlist(rl_PROC_stream_list_cons,	 Splits) :-
 	int16_to_bytecode(290, I290Codes),
 	list__condense([I290Codes], Splits).
-bytecode_to_intlist(rl_PROC_var(X0int32,X1int32),	 Splits) :-
+bytecode_to_intlist(rl_PROC_stream_list_nil,	 Splits) :-
 	int16_to_bytecode(291, I291Codes),
+	list__condense([I291Codes], Splits).
+bytecode_to_intlist(rl_PROC_var(X0int32,X1int32),	 Splits) :-
+	int16_to_bytecode(292, I292Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	int32_to_bytecode(X1int32, X1int32Codes),
-	list__condense([I291Codes,X0int32Codes,X1int32Codes], Splits).
+	list__condense([I292Codes,X0int32Codes,X1int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_indexed_var(X0int32,X1int32,X2aString),	 Splits) :-
-	int16_to_bytecode(292, I292Codes),
+	int16_to_bytecode(293, I293Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	int32_to_bytecode(X1int32, X1int32Codes),
 	int32_to_bytecode(X2aString, X2aStringCodes),
-	list__condense([I292Codes,X0int32Codes,X1int32Codes,X2aStringCodes], Splits).
+	list__condense([I293Codes,X0int32Codes,X1int32Codes,X2aStringCodes], Splits).
 bytecode_to_intlist(rl_PROC_var_list_cons(X0int32,X1int32),	 Splits) :-
-	int16_to_bytecode(293, I293Codes),
+	int16_to_bytecode(294, I294Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	int32_to_bytecode(X1int32, X1int32Codes),
-	list__condense([I293Codes,X0int32Codes,X1int32Codes], Splits).
+	list__condense([I294Codes,X0int32Codes,X1int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_var_list_nil,	 Splits) :-
-	int16_to_bytecode(294, I294Codes),
-	list__condense([I294Codes], Splits).
-bytecode_to_intlist(rl_PROC_expr(X0int32),	 Splits) :-
 	int16_to_bytecode(295, I295Codes),
-	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I295Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_PROC_expr_frag(X0int32),	 Splits) :-
+	list__condense([I295Codes], Splits).
+bytecode_to_intlist(rl_PROC_expr(X0int32),	 Splits) :-
 	int16_to_bytecode(296, I296Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	list__condense([I296Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_PROC_expr_end,	 Splits) :-
+bytecode_to_intlist(rl_PROC_expr_frag(X0int32),	 Splits) :-
 	int16_to_bytecode(297, I297Codes),
-	list__condense([I297Codes], Splits).
-bytecode_to_intlist(rl_PROC_expr_list_cons(X0int32),	 Splits) :-
+	int32_to_bytecode(X0int32, X0int32Codes),
+	list__condense([I297Codes,X0int32Codes], Splits).
+bytecode_to_intlist(rl_PROC_expr_end,	 Splits) :-
 	int16_to_bytecode(298, I298Codes),
+	list__condense([I298Codes], Splits).
+bytecode_to_intlist(rl_PROC_expr_list_cons(X0int32),	 Splits) :-
+	int16_to_bytecode(299, I299Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I298Codes,X0int32Codes], Splits).
+	list__condense([I299Codes,X0int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_expr_list_nil,	 Splits) :-
-	int16_to_bytecode(299, I299Codes),
-	list__condense([I299Codes], Splits).
-bytecode_to_intlist(rl_PROC_bool_op_list_cons,	 Splits) :-
 	int16_to_bytecode(300, I300Codes),
 	list__condense([I300Codes], Splits).
-bytecode_to_intlist(rl_PROC_bool_op_list_nil,	 Splits) :-
+bytecode_to_intlist(rl_PROC_bool_op_list_cons,	 Splits) :-
 	int16_to_bytecode(301, I301Codes),
 	list__condense([I301Codes], Splits).
-bytecode_to_intlist(rl_PROC_int_list_cons(X0int32),	 Splits) :-
+bytecode_to_intlist(rl_PROC_bool_op_list_nil,	 Splits) :-
 	int16_to_bytecode(302, I302Codes),
+	list__condense([I302Codes], Splits).
+bytecode_to_intlist(rl_PROC_int_list_cons(X0int32),	 Splits) :-
+	int16_to_bytecode(303, I303Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I302Codes,X0int32Codes], Splits).
+	list__condense([I303Codes,X0int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_int_list_nil,	 Splits) :-
-	int16_to_bytecode(303, I303Codes),
-	list__condense([I303Codes], Splits).
-bytecode_to_intlist(rl_PROC_ret,	 Splits) :-
 	int16_to_bytecode(304, I304Codes),
 	list__condense([I304Codes], Splits).
-bytecode_to_intlist(rl_PROC_join,	 Splits) :-
+bytecode_to_intlist(rl_PROC_ret,	 Splits) :-
 	int16_to_bytecode(305, I305Codes),
 	list__condense([I305Codes], Splits).
-bytecode_to_intlist(rl_PROC_join_nl,	 Splits) :-
+bytecode_to_intlist(rl_PROC_join,	 Splits) :-
 	int16_to_bytecode(306, I306Codes),
 	list__condense([I306Codes], Splits).
-bytecode_to_intlist(rl_PROC_join_sm,	 Splits) :-
+bytecode_to_intlist(rl_PROC_join_nl,	 Splits) :-
 	int16_to_bytecode(307, I307Codes),
 	list__condense([I307Codes], Splits).
-bytecode_to_intlist(rl_PROC_join_hj,	 Splits) :-
+bytecode_to_intlist(rl_PROC_join_sm,	 Splits) :-
 	int16_to_bytecode(308, I308Codes),
 	list__condense([I308Codes], Splits).
-bytecode_to_intlist(rl_PROC_join_index_simple(X0int32),	 Splits) :-
+bytecode_to_intlist(rl_PROC_join_hj,	 Splits) :-
 	int16_to_bytecode(309, I309Codes),
+	list__condense([I309Codes], Splits).
+bytecode_to_intlist(rl_PROC_join_index_simple(X0int32),	 Splits) :-
+	int16_to_bytecode(310, I310Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I309Codes,X0int32Codes], Splits).
+	list__condense([I310Codes,X0int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_join_index_complex,	 Splits) :-
-	int16_to_bytecode(310, I310Codes),
-	list__condense([I310Codes], Splits).
-bytecode_to_intlist(rl_PROC_join_cross,	 Splits) :-
 	int16_to_bytecode(311, I311Codes),
 	list__condense([I311Codes], Splits).
-bytecode_to_intlist(rl_PROC_semijoin_nl,	 Splits) :-
+bytecode_to_intlist(rl_PROC_join_cross,	 Splits) :-
 	int16_to_bytecode(312, I312Codes),
 	list__condense([I312Codes], Splits).
-bytecode_to_intlist(rl_PROC_semijoin_sm,	 Splits) :-
+bytecode_to_intlist(rl_PROC_semijoin_nl,	 Splits) :-
 	int16_to_bytecode(313, I313Codes),
 	list__condense([I313Codes], Splits).
-bytecode_to_intlist(rl_PROC_semijoin_hj,	 Splits) :-
+bytecode_to_intlist(rl_PROC_semijoin_sm,	 Splits) :-
 	int16_to_bytecode(314, I314Codes),
 	list__condense([I314Codes], Splits).
-bytecode_to_intlist(rl_PROC_semijoin_index(X0int32,X1int32),	 Splits) :-
+bytecode_to_intlist(rl_PROC_semijoin_hj,	 Splits) :-
 	int16_to_bytecode(315, I315Codes),
+	list__condense([I315Codes], Splits).
+bytecode_to_intlist(rl_PROC_semijoin_index(X0int32,X1int32),	 Splits) :-
+	int16_to_bytecode(316, I316Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	int32_to_bytecode(X1int32, X1int32Codes),
-	list__condense([I315Codes,X0int32Codes,X1int32Codes], Splits).
+	list__condense([I316Codes,X0int32Codes,X1int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_subtract,	 Splits) :-
-	int16_to_bytecode(316, I316Codes),
-	list__condense([I316Codes], Splits).
-bytecode_to_intlist(rl_PROC_subtract_nl,	 Splits) :-
 	int16_to_bytecode(317, I317Codes),
 	list__condense([I317Codes], Splits).
-bytecode_to_intlist(rl_PROC_subtract_sm,	 Splits) :-
+bytecode_to_intlist(rl_PROC_subtract_nl,	 Splits) :-
 	int16_to_bytecode(318, I318Codes),
 	list__condense([I318Codes], Splits).
-bytecode_to_intlist(rl_PROC_subtract_hj,	 Splits) :-
+bytecode_to_intlist(rl_PROC_subtract_sm,	 Splits) :-
 	int16_to_bytecode(319, I319Codes),
 	list__condense([I319Codes], Splits).
-bytecode_to_intlist(rl_PROC_subtract_index(X0int32),	 Splits) :-
+bytecode_to_intlist(rl_PROC_subtract_hj,	 Splits) :-
 	int16_to_bytecode(320, I320Codes),
+	list__condense([I320Codes], Splits).
+bytecode_to_intlist(rl_PROC_subtract_index(X0int32),	 Splits) :-
+	int16_to_bytecode(321, I321Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I320Codes,X0int32Codes], Splits).
+	list__condense([I321Codes,X0int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_subtract_cross,	 Splits) :-
-	int16_to_bytecode(321, I321Codes),
-	list__condense([I321Codes], Splits).
-bytecode_to_intlist(rl_PROC_semisubtract_nl,	 Splits) :-
 	int16_to_bytecode(322, I322Codes),
 	list__condense([I322Codes], Splits).
-bytecode_to_intlist(rl_PROC_semisubtract_hj,	 Splits) :-
+bytecode_to_intlist(rl_PROC_semisubtract_nl,	 Splits) :-
 	int16_to_bytecode(323, I323Codes),
 	list__condense([I323Codes], Splits).
-bytecode_to_intlist(rl_PROC_semisubtract_index(X0int32),	 Splits) :-
+bytecode_to_intlist(rl_PROC_semisubtract_hj,	 Splits) :-
 	int16_to_bytecode(324, I324Codes),
+	list__condense([I324Codes], Splits).
+bytecode_to_intlist(rl_PROC_semisubtract_index(X0int32),	 Splits) :-
+	int16_to_bytecode(325, I325Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I324Codes,X0int32Codes], Splits).
+	list__condense([I325Codes,X0int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_difference,	 Splits) :-
-	int16_to_bytecode(325, I325Codes),
-	list__condense([I325Codes], Splits).
-bytecode_to_intlist(rl_PROC_select,	 Splits) :-
 	int16_to_bytecode(326, I326Codes),
 	list__condense([I326Codes], Splits).
-bytecode_to_intlist(rl_PROC_select_filter,	 Splits) :-
+bytecode_to_intlist(rl_PROC_select,	 Splits) :-
 	int16_to_bytecode(327, I327Codes),
 	list__condense([I327Codes], Splits).
-bytecode_to_intlist(rl_PROC_select_index(X0int32),	 Splits) :-
+bytecode_to_intlist(rl_PROC_select_filter,	 Splits) :-
 	int16_to_bytecode(328, I328Codes),
-	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I328Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_PROC_btree_scan(X0int32),	 Splits) :-
+	list__condense([I328Codes], Splits).
+bytecode_to_intlist(rl_PROC_select_index(X0int32),	 Splits) :-
 	int16_to_bytecode(329, I329Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	list__condense([I329Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_PROC_project_tee,	 Splits) :-
+bytecode_to_intlist(rl_PROC_btree_scan(X0int32),	 Splits) :-
 	int16_to_bytecode(330, I330Codes),
-	list__condense([I330Codes], Splits).
-bytecode_to_intlist(rl_PROC_sort(X0int32),	 Splits) :-
+	int32_to_bytecode(X0int32, X0int32Codes),
+	list__condense([I330Codes,X0int32Codes], Splits).
+bytecode_to_intlist(rl_PROC_project_tee,	 Splits) :-
 	int16_to_bytecode(331, I331Codes),
+	list__condense([I331Codes], Splits).
+bytecode_to_intlist(rl_PROC_sort(X0int32),	 Splits) :-
+	int16_to_bytecode(332, I332Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I331Codes,X0int32Codes], Splits).
+	list__condense([I332Codes,X0int32Codes], Splits).
 bytecode_to_intlist(rl_PROC_union,	 Splits) :-
-	int16_to_bytecode(332, I332Codes),
-	list__condense([I332Codes], Splits).
-bytecode_to_intlist(rl_PROC_union_sm,	 Splits) :-
 	int16_to_bytecode(333, I333Codes),
 	list__condense([I333Codes], Splits).
-bytecode_to_intlist(rl_PROC_uniondiff,	 Splits) :-
+bytecode_to_intlist(rl_PROC_union_sm,	 Splits) :-
 	int16_to_bytecode(334, I334Codes),
 	list__condense([I334Codes], Splits).
-bytecode_to_intlist(rl_PROC_uniondiff_sm,	 Splits) :-
+bytecode_to_intlist(rl_PROC_uniondiff,	 Splits) :-
 	int16_to_bytecode(335, I335Codes),
 	list__condense([I335Codes], Splits).
-bytecode_to_intlist(rl_PROC_uniondiff_btree,	 Splits) :-
+bytecode_to_intlist(rl_PROC_uniondiff_sm,	 Splits) :-
 	int16_to_bytecode(336, I336Codes),
 	list__condense([I336Codes], Splits).
-bytecode_to_intlist(rl_PROC_aggregate,	 Splits) :-
+bytecode_to_intlist(rl_PROC_uniondiff_btree,	 Splits) :-
 	int16_to_bytecode(337, I337Codes),
 	list__condense([I337Codes], Splits).
-bytecode_to_intlist(rl_PROC_aggregate_sm,	 Splits) :-
+bytecode_to_intlist(rl_PROC_aggregate,	 Splits) :-
 	int16_to_bytecode(338, I338Codes),
 	list__condense([I338Codes], Splits).
-bytecode_to_intlist(rl_PROC_aggregate_onegroup,	 Splits) :-
+bytecode_to_intlist(rl_PROC_aggregate_sm,	 Splits) :-
 	int16_to_bytecode(339, I339Codes),
 	list__condense([I339Codes], Splits).
-bytecode_to_intlist(rl_PROC_insert_tuple_stream,	 Splits) :-
+bytecode_to_intlist(rl_PROC_aggregate_onegroup,	 Splits) :-
 	int16_to_bytecode(340, I340Codes),
 	list__condense([I340Codes], Splits).
-bytecode_to_intlist(rl_PROC_empty_stream(X0aString),	 Splits) :-
+bytecode_to_intlist(rl_PROC_insert_tuple_stream,	 Splits) :-
 	int16_to_bytecode(341, I341Codes),
+	list__condense([I341Codes], Splits).
+bytecode_to_intlist(rl_PROC_empty_stream(X0aString),	 Splits) :-
+	int16_to_bytecode(342, I342Codes),
 	int32_to_bytecode(X0aString, X0aStringCodes),
-	list__condense([I341Codes,X0aStringCodes], Splits).
+	list__condense([I342Codes,X0aStringCodes], Splits).
 bytecode_to_intlist(rl_PROC_hypothetical,	 Splits) :-
-	int16_to_bytecode(342, I342Codes),
-	list__condense([I342Codes], Splits).
-bytecode_to_intlist(rl_PROC_topdown,	 Splits) :-
 	int16_to_bytecode(343, I343Codes),
 	list__condense([I343Codes], Splits).
-bytecode_to_intlist(rl_PROC_last_bytecode,	 Splits) :-
+bytecode_to_intlist(rl_PROC_topdown,	 Splits) :-
 	int16_to_bytecode(344, I344Codes),
 	list__condense([I344Codes], Splits).
-bytecode_to_intlist(rl_HEAD_proc(X0aString,X1aString,X2aString,X3int32),	 Splits) :-
+bytecode_to_intlist(rl_PROC_last_bytecode,	 Splits) :-
 	int16_to_bytecode(345, I345Codes),
+	list__condense([I345Codes], Splits).
+bytecode_to_intlist(rl_HEAD_proc(X0aString,X1aString,X2aString,X3int32),	 Splits) :-
+	int16_to_bytecode(346, I346Codes),
 	int32_to_bytecode(X0aString, X0aStringCodes),
 	int32_to_bytecode(X1aString, X1aStringCodes),
 	int32_to_bytecode(X2aString, X2aStringCodes),
 	int32_to_bytecode(X3int32, X3int32Codes),
-	list__condense([I345Codes,X0aStringCodes,X1aStringCodes,X2aStringCodes,X3int32Codes], Splits).
+	list__condense([I346Codes,X0aStringCodes,X1aStringCodes,X2aStringCodes,X3int32Codes], Splits).
 bytecode_to_intlist(rl_HEAD_proc_end,	 Splits) :-
-	int16_to_bytecode(346, I346Codes),
-	list__condense([I346Codes], Splits).
-bytecode_to_intlist(rl_HEAD_const_int(X0int32,X1aInt),	 Splits) :-
 	int16_to_bytecode(347, I347Codes),
+	list__condense([I347Codes], Splits).
+bytecode_to_intlist(rl_HEAD_const_int(X0int32,X1aInt),	 Splits) :-
+	int16_to_bytecode(348, I348Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	aInt_to_bytecode(X1aInt, X1aIntCodes),
-	list__condense([I347Codes,X0int32Codes,X1aIntCodes], Splits).
+	list__condense([I348Codes,X0int32Codes,X1aIntCodes], Splits).
 bytecode_to_intlist(rl_HEAD_const_flt(X0int32,X1aDouble),	 Splits) :-
-	int16_to_bytecode(348, I348Codes),
+	int16_to_bytecode(349, I349Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	aDouble_to_bytecode(X1aDouble, X1aDoubleCodes),
-	list__condense([I348Codes,X0int32Codes,X1aDoubleCodes], Splits).
+	list__condense([I349Codes,X0int32Codes,X1aDoubleCodes], Splits).
 bytecode_to_intlist(rl_HEAD_const_str(X0int32,X1aString),	 Splits) :-
-	int16_to_bytecode(349, I349Codes),
+	int16_to_bytecode(350, I350Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	aString_to_bytecode(X1aString, X1aStringCodes),
-	list__condense([I349Codes,X0int32Codes,X1aStringCodes], Splits).
+	list__condense([I350Codes,X0int32Codes,X1aStringCodes], Splits).
 bytecode_to_intlist(rl_HEAD_var_int(X0int32),	 Splits) :-
-	int16_to_bytecode(350, I350Codes),
-	int32_to_bytecode(X0int32, X0int32Codes),
-	list__condense([I350Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_HEAD_var_flt(X0int32),	 Splits) :-
 	int16_to_bytecode(351, I351Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	list__condense([I351Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_HEAD_var_str(X0int32),	 Splits) :-
+bytecode_to_intlist(rl_HEAD_var_flt(X0int32),	 Splits) :-
 	int16_to_bytecode(352, I352Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	list__condense([I352Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_HEAD_var_term(X0int32),	 Splits) :-
+bytecode_to_intlist(rl_HEAD_var_str(X0int32),	 Splits) :-
 	int16_to_bytecode(353, I353Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	list__condense([I353Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_HEAD_var_stream(X0int32),	 Splits) :-
+bytecode_to_intlist(rl_HEAD_var_term(X0int32),	 Splits) :-
 	int16_to_bytecode(354, I354Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
 	list__condense([I354Codes,X0int32Codes], Splits).
-bytecode_to_intlist(rl_HEAD_define_rule(X0int32,X1aString,X2aString),	 Splits) :-
+bytecode_to_intlist(rl_HEAD_var_stream(X0int32),	 Splits) :-
 	int16_to_bytecode(355, I355Codes),
 	int32_to_bytecode(X0int32, X0int32Codes),
+	list__condense([I355Codes,X0int32Codes], Splits).
+bytecode_to_intlist(rl_HEAD_define_rule(X0int32,X1aString,X2aString),	 Splits) :-
+	int16_to_bytecode(356, I356Codes),
+	int32_to_bytecode(X0int32, X0int32Codes),
 	int32_to_bytecode(X1aString, X1aStringCodes),
 	int32_to_bytecode(X2aString, X2aStringCodes),
-	list__condense([I355Codes,X0int32Codes,X1aStringCodes,X2aStringCodes], Splits).
+	list__condense([I356Codes,X0int32Codes,X1aStringCodes,X2aStringCodes], Splits).
 bytecode_to_intlist(rl_HEAD_last_bytecode,	 Splits) :-
-	int16_to_bytecode(356, I356Codes),
-	list__condense([I356Codes], Splits).
+	int16_to_bytecode(357, I357Codes),
+	list__condense([I357Codes], Splits).
 
 int32_to_bytecode(X, List) :-
 	int32_to_byte_list(X, List).
@@ -1740,4 +1745,4 @@
 	int_to_byte_list(X, List).
 
 
-rl_code__version(1, 26).
+rl_code__version(1, 27).
Index: rl_dump.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_dump.m,v
retrieving revision 1.6
diff -u -u -r1.6 rl_dump.m
--- rl_dump.m	2000/03/01 01:04:49	1.6
+++ rl_dump.m	2000/03/10 03:56:25
@@ -257,9 +257,10 @@
 	io__nl.
 
 rl_dump__write_instruction(_ModuleInfo, RelationInfo,
-		add_index(OutputRel) - Comment) -->
-	io__write_string("add_index("),
-	rl_dump__write_output_rel(RelationInfo, OutputRel),
+		add_index(Output, Input) - Comment) -->
+	rl_dump__write_output_rel(RelationInfo, Output),
+	io__write_string(" = add_index("),
+	rl_dump__write_relation_id(RelationInfo, Input),
 	io__write_string(")."),
 	rl_dump__write_comment(Comment),
 	io__nl.
@@ -601,8 +602,8 @@
 		relation_id::in, io__state::di, io__state::uo) is det.
 
 rl_dump__write_relation_id(_, RelationId) -->
-	io__write_string("Rel_"),
-	io__write_int(RelationId).
+	{ rl__relation_id_to_string(RelationId, RelationIdStr) },
+	io__write_string(RelationIdStr).
 
 :- pred rl_dump__verbose_write_relation_id(
 		map(relation_id, relation_info)::in,
Index: rl_out.pp
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_out.pp,v
retrieving revision 1.11
diff -u -u -r1.11 rl_out.pp
--- rl_out.pp	2000/03/01 01:04:50	1.11
+++ rl_out.pp	2000/03/13 01:19:21
@@ -643,8 +643,28 @@
 		node([rl_PROC_expr(CompareExprn)])
 	)) },
 	rl_out__generate_stream_instruction(Output, InstrCode, Code).
-rl_out__generate_instr(add_index(output_rel(Rel, Indexes)) - _, Code) -->
-	rl_out__add_indexes_to_rel(may_have_index, Rel, Indexes, Code).
+rl_out__generate_instr(add_index(output_rel(Rel, Indexes), Input) - _,
+		Code) -->
+	% Generated as 
+	% if (is_permanent(Input) and !has_index(Input, Indexes)) {
+	% 	copy(Output, Input);
+	% } else {
+	%	ref(Output, Input);
+	% 	if (has_index(Input, Indexes)) {
+	%		;
+	%	} else {
+	%		rl_PROC_add_index(Output, Indexes);
+	%	}
+	% }
+	%
+	rl_out__generate_test_for_non_indexed_permanent(Input,
+		Indexes, CondCode),
+	rl_out__generate_instr(copy(output_rel(Rel, Indexes), Input) - "",
+		ThenCode),
+	rl_out__generate_instr(ref(Rel, Input) - "", RefCode),
+	rl_out__add_indexes_to_rel(may_have_index, Rel, Indexes, IndexCode),
+	{ ElseCode = tree(RefCode, IndexCode) },
+	rl_out__generate_ite(CondCode, ThenCode, ElseCode, Code).
 rl_out__generate_instr(clear(Rel) - _, Code) -->
 	rl_out_info_get_relation_addr(Rel, Addr),
 	{ Code = node([rl_PROC_clear(Addr)]) }.
@@ -723,19 +743,17 @@
 	) }.
 rl_out__generate_instr(make_unique(OutputRel, Input) - Comment, Code) -->
 	% 	if (one_reference(InputRel)) {
-	% 		OutputRel = ref(InputRel)
+	% 		OutputRel = add_index(InputRel)
 	% 	} else {
 	% 		OutputRel = copy(InputRel)
 	%	}
 	rl_out_info_get_relation_addr(Input, InputAddr),
 	{ CondCode = node([rl_PROC_one_reference(InputAddr)]) },
 
-	{ OutputRel = output_rel(Output, _) },
-	rl_out__generate_instr(ref(Output, Input) - Comment, ThenCode0),
 	% We may not need to generate this instruction - rl_sort.m
 	% has enough information to work out whether this is actually needed.
-	rl_out__generate_instr(add_index(OutputRel) - Comment, ThenCode1),
-	{ ThenCode = tree(ThenCode0, ThenCode1) },
+	rl_out__generate_instr(add_index(OutputRel, Input) - Comment,
+		ThenCode),
 
 	rl_out__generate_instr(copy(OutputRel, Input) - Comment, ElseCode),
 
@@ -757,7 +775,7 @@
 	rl_out_info_assign_const(string(ProcNameStr), ProcNameConst),
 	rl_out_info_return_tmp_vars(SaveTmpVars, SaveClearCode),
 	rl_out_info_return_tmp_vars(OverlapTmpVars, OverlapClearCode),
-	rl_out__add_indexes_to_rels(does_not_have_index,
+	rl_out__add_indexes_to_rels_copy_permanents(may_have_index,
 		OutputRels, IndexCode),
 	{ Code =
 		tree(SaveCode,
@@ -1448,6 +1466,40 @@
 	;	does_not_have_index
 	.
 
+:- pred rl_out__add_indexes_to_rels_copy_permanents(check_index::in, 
+		list(output_rel)::in, byte_tree::out,
+		rl_out_info::in, rl_out_info::out) is det.
+
+rl_out__add_indexes_to_rels_copy_permanents(CheckIndex,
+		OutputRels, IndexCode) -->
+	list__foldl2(rl_out__add_indexes_to_rel_copy_permanent(CheckIndex),
+		OutputRels, empty, IndexCode).
+
+:- pred rl_out__add_indexes_to_rel_copy_permanent(check_index::in,
+		output_rel::in, byte_tree::in, byte_tree::out,
+		rl_out_info::in, rl_out_info::out) is det.
+
+rl_out__add_indexes_to_rel_copy_permanent(CheckIndex,
+		OutputRel, Code0, Code) -->
+	{ OutputRel = output_rel(Output, Indexes) },
+	(
+		{ Indexes = [] },
+		{ Code = Code0 }
+	;
+		{ Indexes = [_ | _] },
+		rl_out__generate_test_for_non_indexed_permanent(Output,
+			Indexes, CondCode),
+	
+		% Copy the base relation, because queries can't add
+		% indexes to a base relation.
+		rl_out__generate_instr(copy(OutputRel, Output) - "",
+			CopyCode),	
+
+		rl_out__add_indexes_to_rel(CheckIndex, Output,
+			Indexes, IndexCode),
+		rl_out__generate_ite(CondCode, CopyCode, IndexCode, Code)
+	).
+
 :- pred rl_out__add_indexes_to_rels(check_index::in,
 		list(output_rel)::in, byte_tree::out,
 		rl_out_info::in, rl_out_info::out) is det.
@@ -1492,6 +1544,54 @@
 		OutputAddr, Indexes, IndexCode1),
 	{ IndexCode = tree(IndexCode0, IndexCode1) }.
 
+	% Test whether the input relation is a base relation which does
+	% not have one of the given indexes. If we are going to add
+	% the indexes, the base relation needs to be copied (queries should
+	% never add indexes to base relations).
+:- pred rl_out__generate_test_for_non_indexed_permanent(relation_id::in,
+		list(index_spec)::in, byte_tree::out,
+		rl_out_info::in, rl_out_info::out) is det.
+
+rl_out__generate_test_for_non_indexed_permanent(Input, Indexes, CondCode) -->
+	rl_out_info_get_relation_addr(Input, InputAddr),
+	{ GenerateHasIndexCode =
+	    (pred(Index::in, HasIndexCode::out, Info0::in, Info::out) is det :-
+			rl_out__index_spec_to_string(Index, IndexStr),
+			rl_out_info_assign_const(string(IndexStr), IndexConst,
+				Info0, Info),
+			HasIndexCode = node([
+				rl_PROC_not,
+				rl_PROC_has_index(InputAddr, IndexConst)
+			])
+	    ) },
+	list__map_foldl(GenerateHasIndexCode, Indexes, IndexTests),
+
+	{
+		IndexTests = [IndexTest | IndexTests1],
+		CombineTest =
+			(pred(Test1::in, CombinedCode0::in,
+					CombinedCode::out) is det :-
+				CombinedCode =
+					tree(node([rl_PROC_or]),
+					tree(Test1,
+					CombinedCode0
+				))
+			),
+		list__foldl(CombineTest, IndexTests1,
+			IndexTest, IndexTestCode),
+		CondCode =
+			tree(node([
+				rl_PROC_and,
+				rl_PROC_is_permanent(InputAddr)
+			]),
+			IndexTestCode
+		)
+	;
+		IndexTests = [],
+		error(
+	"rl_out__generate_test_for_non_indexed_permanent: no indexes")
+	}.
+
 %-----------------------------------------------------------------------------%
 
 	% Generate code to handle an instruction that could return a
@@ -1568,14 +1668,13 @@
 		%
 		rl_out__generate_instr(copy(OutputRel, Input) - "", Code)
 	;
-		rl_out__generate_instr(ref(Output, Input) - "", RefCode),
 		( { Indexes = [] } ->
-			{ IndexCode = empty }
+			rl_out__generate_instr(ref(Output, Input) - "", Code)
 		;
-			rl_out__generate_instr(add_index(OutputRel) - "",
-				IndexCode)
-		),
-		{ Code = tree(RefCode, IndexCode) }
+			rl_out__generate_instr(
+				add_index(OutputRel, Input) - "",
+				Code)
+		)
 	).
 
 %-----------------------------------------------------------------------------%
Index: rl_sort.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_sort.m,v
retrieving revision 1.7
diff -u -u -r1.7 rl_sort.m
--- rl_sort.m	2000/03/01 01:04:52	1.7
+++ rl_sort.m	2000/03/10 04:00:47
@@ -172,7 +172,8 @@
 	;	index(index_spec)	
 	.
 
-:- type relation_sort_map == map(relation_id, map(sort_index, sort_req)).
+:- type relation_sort_map == map(relation_id, sort_req_map).
+:- type sort_req_map == map(sort_index, sort_req).
 :- type var_sort_map == map(int, set(relation_id)).
 
 	% Possible sortednesses for each sortedness variable.
@@ -300,57 +301,140 @@
 :- pred rl_sort__merge_maps(map(T, set(U))::in, map(T, set(U))::in, 
 		map(T, set(U))::out) is det.
 
-rl_sort__merge_maps(Map1, Map2, Map) :-
-	AddToMap =
-	    lambda([Key::in, Value::in, MergedMap0::in, MergedMap::out] is det, 
-	    (
-	    	( map__search(MergedMap0, Key, Value0) ->
-			set__union(Value0, Value, MergedValue),
-			map__det_update(MergedMap0, Key,
-				MergedValue, MergedMap)
-		;
-			map__det_insert(MergedMap0, Key, Value, MergedMap)
-		)
-	    )),
-	map__foldl(AddToMap, Map2, Map1, Map).
+rl_sort__merge_maps(Map1, Map2, NewMap) :-
+	UnionValues =
+		(pred(_::in, Value1::in, Value2::in, Value::out) is semidet :-
+			set__union(Value1, Value2, Value)
+		),
+	Id = (pred(_::in, Value::in, Value::out) is semidet),
+	merge_map_keys(UnionValues, Id, Map1, Map2, NewMap).
+
+:- pred merge_map_keys(pred(K, V, V, V)::(pred(in, in, in, out) is semidet),
+		pred(K, V, V)::(pred(in, in, out) is semidet),
+		map(K, V)::in, map(K, V)::in, map(K, V)::out) is det.
+
+merge_map_keys(UnionValues, Id, Map1, Map2, MergedMap) :-
+	map__keys(Map1, Keys1),
+	map__keys(Map2, Keys2),
+	list__append(Keys1, Keys2, Keys),
+	list__sort_and_remove_dups(Keys, SortedKeys),
+	map__init(MergedMap0),
+	list__foldl(merge_map_key(UnionValues, Id, Map1, Map2),
+		SortedKeys, MergedMap0, MergedMap).
+
+:- pred merge_map_key(pred(K, V, V, V)::(pred(in, in, in, out) is semidet),
+		pred(K, V, V)::(pred(in, in, out) is semidet),
+		map(K, V)::in, map(K, V)::in, K::in,
+		map(K, V)::in, map(K, V)::out) is det.
+
+merge_map_key(Merge, Single, Map1, Map2, Key, MergedMap0, MergedMap) :-
+	maybe_map_search(Map1, Key, MaybeValue1),
+	maybe_map_search(Map2, Key, MaybeValue2),
+	(
+		merge_maybes(Merge, Single, Key, MaybeValue1, MaybeValue2,
+			Value)
+	->
+		map__det_insert(MergedMap0, Key, Value, MergedMap)
+	;
+		MergedMap = MergedMap0
+	).
+
+:- pred maybe_map_search(map(K, V)::in, K::in, maybe(V)::out) is det.
 
+maybe_map_search(Map, Key, MaybeValue) :-
+	( map__search(Map, Key, Value) ->
+		MaybeValue = yes(Value)
+	;
+		MaybeValue = no
+	).
+
+:- pred merge_maybes(pred(K, V, V, V)::(pred(in, in, in, out) is semidet),
+		pred(K, V, V)::(pred(in, in, out) is semidet),
+		K::in, maybe(V)::in, maybe(V)::in, V::out) is semidet.
+
+merge_maybes(Merge, _, K, yes(V1), yes(V2), V) :- Merge(K, V1, V2, V).
+merge_maybes(_, Single, K, yes(V1), no, V) :- Single(K, V1, V).
+merge_maybes(_, Single, K, no, yes(V2), V) :- Single(K, V2, V).
+
+:- pred rl_sort__semidet_merge_sort_maps(relation_sort_map::in,
+		relation_sort_map::in, relation_sort_map::out) is semidet.
+
+rl_sort__semidet_merge_sort_maps(A, B, C) :-
+	rl_sort__merge_sort_maps(A, B, C),
+	semidet_succeed.
+
 :- pred rl_sort__merge_sort_maps(relation_sort_map::in, relation_sort_map::in,
 		relation_sort_map::out) is det.
 
-rl_sort__merge_sort_maps(SortSpecs, Specs0, Specs) :-
+rl_sort__merge_sort_maps(RelSortMap1, RelSortMap2, RelSortMap) :-
+	MergeValues = semidet_merge_sort_req_map,
+	SingleValue = semidet_definite_to_maybe_sort_req_map,
+	merge_map_keys(MergeValues, SingleValue,
+		RelSortMap1, RelSortMap2, RelSortMap).
 
-	MergeMaps =
-	    lambda([Key::in, Value1::in, MergedMap0::in, MergedMap::out] is det,
-	    (
-	    	( map__search(MergedMap0, Key, Value0) ->
-			rl_sort__merge_sort_maps_2(Value1, Value0, Value),
-			map__det_update(MergedMap0, Key, Value, MergedMap)
-		;
-			map__det_insert(MergedMap0, Key, Value1, MergedMap)
-		)
-	    )),
-	map__foldl(MergeMaps, SortSpecs, Specs0, Specs).
+:- pred rl_sort__semidet_merge_sort_req_map(relation_id::in, sort_req_map::in,
+		sort_req_map::in, sort_req_map::out) is semidet.
 
-:- pred rl_sort__merge_sort_maps_2(map(sort_index, sort_req)::in, 
-	map(sort_index, sort_req)::in, map(sort_index, sort_req)::out) is det. 
+rl_sort__semidet_merge_sort_req_map(A, B, C, D) :-
+	rl_sort__merge_sort_req_map(A, B, C, D),
+	semidet_succeed.
 
-rl_sort__merge_sort_maps_2(Map0, Map1, Map) :-
-	MergeMaps =
-	    lambda([Spec::in, Req1::in, MergedMap0::in, MergedMap::out] is det,
-	    (
-	    	( map__search(MergedMap0, Spec, Req0) ->
-			rl_sort__merge_sort_reqs(Req0, Req1, Req),
-			map__det_update(MergedMap0, Spec, Req, MergedMap)
-		;
-			map__det_insert(MergedMap0, Spec, Req1, MergedMap)
-		)
-	    )),
-	map__foldl(MergeMaps, Map0, Map1, Map).
+:- pred rl_sort__merge_sort_req_map(relation_id::in, sort_req_map::in,
+		sort_req_map::in, sort_req_map::out) is det.
+
+rl_sort__merge_sort_req_map(_, SortReqMap1, SortReqMap2, SortReqMap) :-
+	MergeValue = rl_sort__semidet_merge_sort_reqs,
+	SingleValue = rl_sort__semidet_definite_to_maybe_sort_req,
+	merge_map_keys(MergeValue, SingleValue, SortReqMap1,
+		SortReqMap2, SortReqMap).
+
+:- pred rl_sort__union_sort_req_map(relation_id::in, sort_req_map::in,
+		sort_req_map::in, sort_req_map::out) is det.
+
+rl_sort__union_sort_req_map(_, SortReqMap1, SortReqMap2, SortReqMap) :-
+	MergeValue = rl_sort__semidet_merge_sort_reqs,
+	SingleValue = (pred(_::in, X::in, X::out) is semidet),
+	merge_map_keys(MergeValue, SingleValue, SortReqMap1,
+		SortReqMap2, SortReqMap).
+
+:- pred semidet_definite_to_maybe_sort_req_map(relation_id::in,
+		sort_req_map::in, sort_req_map::out) is semidet.
+
+semidet_definite_to_maybe_sort_req_map(A, B, C) :-
+	definite_to_maybe_sort_req_map(A, B, C),
+	semidet_succeed.
+
+:- pred definite_to_maybe_sort_req_map(relation_id::in,
+		sort_req_map::in, sort_req_map::out) is det.
 
-:- pred rl_sort__merge_sort_reqs(sort_req::in,
+definite_to_maybe_sort_req_map(_, SortReqMap0, SortReqMap) :-
+	map__map_values(rl_sort__definite_to_maybe_sort_req,
+		SortReqMap0, SortReqMap).
+
+:- pred rl_sort__semidet_definite_to_maybe_sort_req(sort_index::in,
+		sort_req::in, sort_req::out) is semidet.
+
+rl_sort__semidet_definite_to_maybe_sort_req(A, B, C) :-
+	rl_sort__definite_to_maybe_sort_req(A, B, C),
+	semidet_succeed.
+
+:- pred rl_sort__definite_to_maybe_sort_req(sort_index::in, sort_req::in,
+		sort_req::out) is det.
+
+rl_sort__definite_to_maybe_sort_req(_, sort_req(_, BlockIds),
+		sort_req(maybe, BlockIds)).
+
+:- pred rl_sort__semidet_merge_sort_reqs(sort_index::in, sort_req::in,
+		sort_req::in, sort_req::out) is semidet.
+
+rl_sort__semidet_merge_sort_reqs(A, B, C, D) :-
+	rl_sort__merge_sort_reqs(A, B, C, D),
+	semidet_succeed.
+
+:- pred rl_sort__merge_sort_reqs(sort_index::in, sort_req::in,
 		sort_req::in, sort_req::out) is det.
 
-rl_sort__merge_sort_reqs(Req0, Req1, Req) :-
+rl_sort__merge_sort_reqs(_, Req0, Req1, Req) :-
 	Req0 = sort_req(Definite0, BlockIds0),
 	Req1 = sort_req(Definite1, BlockIds1),
 	set__union(BlockIds0, BlockIds1, BlockIds),
@@ -413,7 +497,7 @@
 		map__keys(SortSpecs0, Specs0),
 		set__sorted_list_to_set(Specs0, SpecSet0),
 		rl_sort__get_vars(SpecSet0, Vars0),
-		rl_sort__merge_sort_maps_2(NewSortSpecs,
+		rl_sort__union_sort_req_map(RelationId, NewSortSpecs,
 			SortSpecs0, SortSpecs),
 		map__det_update(RelMap0, RelationId, SortSpecs, RelMap)
 	;
@@ -700,7 +784,7 @@
 	% An aggregate's input is sorted on both attributes.
 	rl_sort__add_relation_sortedness(BlockId,
 		sort(attributes([1 - ascending, 2 - ascending])), Input).
-rl_sort__instr_needed(_BlockId, add_index(_Output) - _) --> [].
+rl_sort__instr_needed(_BlockId, add_index(_Output, _) - _) --> [].
 rl_sort__instr_needed(_, clear(_) - _) --> [].
 rl_sort__instr_needed(_, unset(Relation) - _) -->
 	rl_sort__unset_relation(Relation).
@@ -871,7 +955,7 @@
 	rl_sort__add_relation_sortedness(BlockId,
 		sort(attributes([1 - ascending, 2 - ascending])), OutputRel),
 	rl_sort__handle_output_indexing(BlockId, Output).
-rl_sort__instr_avail(BlockId, add_index(Output) - _) -->
+rl_sort__instr_avail(BlockId, add_index(Output, _) - _) -->
 	rl_sort__handle_output_indexing(BlockId, Output).
 rl_sort__instr_avail(_, clear(_) - _) --> [].
 rl_sort__instr_avail(_, unset(Relation) - _) -->
@@ -1385,7 +1469,7 @@
 	(pred(SortIndex::in, SortReq::in, Specs0::in, Specs::out) is det :-
 		(
 			SortReq = sort_req(definite, _),
-			(
+			%(
 				SortIndex = sort(SortSpec),
 				SortSpec = attributes(SortAttrs),
 				\+ (
@@ -1399,6 +1483,9 @@
 					list__member(SortAttr, SortAttrs),
 					SortAttr = _ - descending
 				)
+			/*
+				% If a relation is definitely indexed, we
+				% should be doing an indexed join.
 			;
 				% B-tree indexed relations are sorted
 				% on the indexed attributes.
@@ -1413,6 +1500,7 @@
 					SortDirs, SortAttrs),
 				SortSpec = attributes(SortAttrs)
 			)
+			*/
 		->
 			Specs = [SortSpec | Specs0]
 		;
@@ -1656,16 +1744,16 @@
 		Instr, Instrs0, Instrs) -->
 	=(sort_info(sortedness(RelSortMap, _), _, _)),
 	(
-		{ Instr = add_index(OutputRel0) - Comm }
+		{ Instr = add_index(OutputRel0, Input) - Comm }
 	->
 		{ rl_sort__map_output_rel(RelSortMap, rl_sort__map_spec,
 			OutputRel0, OutputRel) },
 		{ OutputRel = output_rel(Relation, NeededIndexes) },
 		{ NeededIndexes = [] ->
-			Instrs = Instrs0
+			Instrs = [ref(Relation, Input) - Comm | Instrs0]
 		;
 			Instrs = [add_index(output_rel(Relation, 
-				NeededIndexes)) - Comm | Instrs0]
+				NeededIndexes), Input) - Comm | Instrs0]
 		}
 	;
 		{ Instr = sort(Output0, Input, SortSpec) - Comm }
@@ -1690,8 +1778,7 @@
 			list__foldl2(
 			    rl_sort__add_indexing_and_remove_useless_ops_instr(
 			    	BlockId),
-				[add_index(Output) - Comm,
-				ref(OutputRel, Input) - Comm],
+				[add_index(Output, Input) - Comm],
 				Instrs0, Instrs)
 		;
 			{ SpecNeeded = yes },
@@ -1915,8 +2002,8 @@
 		aggregate(Output, B, C, D) - E) :-
 	call(OutputPred, Output0, Output).
 rl_sort__map_sort_and_index_specs(OutputPred, _, _,
-		add_index(Output0) - Comm,
-		add_index(Output) - Comm) :-
+		add_index(Output0, Input) - Comm,
+		add_index(Output, Input) - Comm) :-
 	call(OutputPred, Output0, Output).
 rl_sort__map_sort_and_index_specs(_, _, _, Instr, Instr) :-
 	Instr = clear(_) - _.
Index: rl_stream.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_stream.m,v
retrieving revision 1.4
diff -u -u -r1.4 rl_stream.m
--- rl_stream.m	2000/03/01 01:04:52	1.4
+++ rl_stream.m	2000/03/10 03:52:47
@@ -443,7 +443,8 @@
 	rl_stream__output_is_indexed(Output, Materialise).
 
 	% Indexed relations must always be materialised.
-rl_stream__must_materialise_rels(add_index(output_rel(Rel, _)) - _, [Rel]).
+rl_stream__must_materialise_rels(add_index(output_rel(Output, _), Input) - _,
+		[Input, Output]).
 rl_stream__must_materialise_rels(clear(Rel) - _, [Rel]).
 rl_stream__must_materialise_rels(ref(_, _) - _, []).
 rl_stream__must_materialise_rels(copy(output_rel(Output, _), Input) - _,
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list