// Merge // public static MergePlan RenderMergePlan(Workspace Home, HScriptParser.Crudam_mergeContext context) { // Get the data sources // DataSet data1 = VisitorHelper.GetData(Home, context.merge_source()[0].full_table_name()); DataSet data2 = VisitorHelper.GetData(Home, context.merge_source()[1].full_table_name()); // Get the aliases // string alias1 = (context.merge_source()[0].IDENTIFIER() ?? context.merge_source()[0].full_table_name().table_name().IDENTIFIER()).GetText(); string alias2 = (context.merge_source()[1].IDENTIFIER() ?? context.merge_source()[1].full_table_name().table_name().IDENTIFIER()).GetText(); // Build the registers; the join functions only use static registers // StaticRegister mem1 = new StaticRegister(null); StaticRegister mem2 = new StaticRegister(null); // Create our expression builder // ExpressionVisitor exp_vis = new ExpressionVisitor(null, Home); exp_vis.AddSchema(alias1, data1.Columns, mem1); exp_vis.AddSchema(alias2, data2.Columns, mem2); // Get the equality keys // Key eq1 = new Key(); Key eq2 = new Key(); foreach (HScriptParser.Merge_equi_predicateContext ctx in context.merge_equi_predicate()) { string a1 = ctx.table_variable()[0].IDENTIFIER()[0].GetText(); string a2 = ctx.table_variable()[1].IDENTIFIER()[0].GetText(); string c1 = ctx.table_variable()[0].IDENTIFIER()[1].GetText(); string c2 = ctx.table_variable()[1].IDENTIFIER()[1].GetText(); int idx1 = -1; int idx2 = -1; if (a1 == alias1 && a2 == alias2) { // Look up indicides // idx1 = data1.Columns.ColumnIndex(c1); idx2 = data2.Columns.ColumnIndex(c2); // Check for invalid keys // if (idx1 == -1) throw new Exception(string.Format("Column '{0}' does not exist in '{1}'", c1, alias1)); if (idx2 == -1) throw new Exception(string.Format("Column '{0}' does not exist in '{1}'", c2, alias2)); } else if (a1 == alias2 && a2 == alias1) { // Look up indicides // idx1 = data1.Columns.ColumnIndex(c2); idx2 = data2.Columns.ColumnIndex(c1); // Check for invalid keys // if (idx1 == -1) throw new Exception(string.Format("Column '{0}' does not exist in '{1}'", c2, idx1)); if (idx2 == -1) throw new Exception(string.Format("Column '{0}' does not exist in '{1}'", c1, idx2)); } else throw new Exception("Aliases passed are invalid"); // add the keys // eq1.Add(idx1); eq2.Add(idx2); } // Get the predicate // Predicate where = VisitorHelper.GetWhere(exp_vis, context.where_clause()); // Get the list of expressions // FNodeSet nodes = VisitorHelper.GetReturnStatement(exp_vis, context.return_action().expression_or_wildcard_set()); // Get the output cursor // RecordWriter out_data = VisitorHelper.GetWriter(Home, nodes.Columns, context.return_action()); // Get the join method // MergeMethod method = VisitorHelper.GetMergeMethod(context.merge_type()); // Find the best algorithm // MergeAlgorithm alg = MergeAlgorithm.SortMerge; if (context.merge_algorithm() != null) { string suggest_alg = exp_vis.ToNode(context.merge_algorithm().expression()).Evaluate().valueSTRING.ToUpper(); if (suggest_alg == "NL") alg = MergeAlgorithm.NestedLoop; else if (suggest_alg == "SM") alg = MergeAlgorithm.SortMerge; else if (suggest_alg == "HT") alg = MergeAlgorithm.HashTable; } if (eq1.Count == 0) alg = MergeAlgorithm.NestedLoop; return new MergePlan(method, alg, out_data, nodes, where, data1, data2, eq1, eq2, mem1, mem2); }