@@ -237,18 +237,6 @@ public Env transformJoin(Env env, RelRN.Join join) {
237237 String rightVar = env .bindings ().get ("right" );
238238 String onVar = env .bindings ().get ("on" );
239239 String privateVar = env .bindings ().get ("private" );
240-
241- // Check if join condition is True (JoinExtractFilter pattern)
242- if (join .cond () instanceof RexRN .True ) {
243- String pattern = "(InnerJoin\n "
244- + " $" + leftVar + "\n "
245- + " $" + rightVar + "\n "
246- + " []\n "
247- + " $" + privateVar + "\n "
248- + ")" ;
249- return env .setPattern (pattern ).focus (pattern );
250- }
251-
252240 String pattern = "(InnerJoin\n "
253241 + " (Select $" + leftVar + " (ExtractBoundConditions $" + onVar + " (OutputCols $" + leftVar + ")))\n "
254242 + " (Select $" + rightVar + " (ExtractBoundConditions $" + onVar + " (OutputCols $" + rightVar + ")))\n "
@@ -378,22 +366,6 @@ private String buildNestedIntersect(String intersectType, Seq<String> sources, S
378366
379367 @ Override
380368 public Env onMatchMinus (Env env , RelRN .Minus minus ) {
381- if (minus .sources ().size () == 2 ) {
382- RelRN leftSource = minus .sources ().get (0 );
383- RelRN rightSource = minus .sources ().get (1 );
384- if (leftSource instanceof RelRN .Empty ) {
385- String leftVar = env .generateVar ("left" );
386- Env leftEnv = env .addBinding ("left" , leftVar );
387- String rightVar = leftEnv .generateVar ("right" );
388- Env rightEnv = leftEnv .addBinding ("right" , rightVar );
389- // Still need to match the right source to get its pattern, but we'll use our variable name
390- Env rightSourceEnv = onMatch (rightEnv , rightSource );
391- String pattern = "(Except\n $" + leftVar + ":* & (HasZeroRows $" + leftVar + ")\n $" + rightVar + ":*\n )" ;
392- return rightSourceEnv .addBinding ("isPruneEmptyMinus" , "true" )
393- .addBinding ("pruneEmptyLeft" , leftVar )
394- .setPattern (pattern ).focus (pattern );
395- }
396- }
397369 if (minus .sources ().size () == 2 && minus .sources ().get (0 ) instanceof RelRN .Minus inner ) {
398370 String leftVar = env .generateVar ("left" );
399371 Env leftEnv = env .addBinding ("left" , leftVar );
@@ -870,11 +842,6 @@ private String buildNestedIntersectTransform(String intersectType, Seq<String> s
870842
871843 @ Override
872844 public Env transformMinus (Env env , RelRN .Minus minus ) {
873- if (env .bindings ().containsKey ("isPruneEmptyMinus" )) {
874- String leftVar = env .bindings ().get ("pruneEmptyLeft" );
875- String pattern = "(ConstructEmptyValues (OutputCols $" + leftVar + "))" ;
876- return env .setPattern (pattern ).focus (pattern );
877- }
878845 String pattern = "(Except\n "
879846 + " $left\n "
880847 + " (Union\n "
@@ -1024,26 +991,6 @@ private Env transformGroupSet(Env env, Seq<RexRN> groupSet) {
1024991
1025992 @ Override
1026993 public Env transformEmpty (Env env , RelRN .Empty empty ) {
1027- // Check for any pruneEmpty* binding (generic, not rule-specific)
1028- // Try common pruneEmpty binding names
1029- String pruneVar = null ;
1030- boolean needsConstructEmptyValues = false ;
1031- if (env .bindings ().containsKey ("pruneEmptyLeft" )) {
1032- pruneVar = env .bindings ().get ("pruneEmptyLeft" );
1033- needsConstructEmptyValues = true ;
1034- } else if (env .bindings ().containsKey ("pruneEmptyInput" )) {
1035- pruneVar = env .bindings ().get ("pruneEmptyInput" );
1036- needsConstructEmptyValues = false ;
1037- }
1038- if (pruneVar != null ) {
1039- if (needsConstructEmptyValues ) {
1040- String pattern = "(ConstructEmptyValues (OutputCols $" + pruneVar + "))" ;
1041- return env .setPattern (pattern ).focus (pattern );
1042- } else {
1043- String pattern = "$" + pruneVar ;
1044- return env .setPattern (pattern ).focus (pattern );
1045- }
1046- }
1047994 if (env .bindings ().containsKey ("hasZeroRows" )) {
1048995 String inputVar = env .bindings ().getOrDefault ("zeroInput" , "input" );
1049996 String patternStr = env .pattern ();
@@ -1054,6 +1001,11 @@ public Env transformEmpty(Env env, RelRN.Empty empty) {
10541001 String pattern = "$" + inputVar ;
10551002 return env .setPattern (pattern ).focus (pattern );
10561003 }
1004+ if (env .bindings ().containsKey ("isPruneEmptyFilter" )) {
1005+ String inputVar = env .bindings ().get ("pruneEmptyInput" );
1006+ String pattern = "$" + inputVar ;
1007+ return env .setPattern (pattern ).focus (pattern );
1008+ }
10571009 String pattern = "(ConstructEmptyValues (OutputCols $input_0))" ;
10581010 return env .setPattern (pattern ).focus (pattern );
10591011 }
@@ -1168,30 +1120,9 @@ else if (match.startsWith("(Union\n")) {
11681120 match = "(" + unionType + "\n $" + leftVar + ":* & (HasZeroRows $" + leftVar + ")\n $" + rightVar + ":* & (HasZeroRows $" + rightVar + ")\n )" ;
11691121 }
11701122 }
1171- // Extract variable map early for potential normalization (before appending match)
1172- java .util .Map <String , String > varMapForNormalization = extractNumberedVarMap (match );
1173- String out = transform .pattern ();
1174- // Normalize match pattern for JoinExtractFilter before appending
1175- if (!varMapForNormalization .isEmpty () && match .startsWith ("(InnerJoin" ) &&
1176- varMapForNormalization .containsKey ("left" ) && varMapForNormalization .containsKey ("right" ) &&
1177- varMapForNormalization .containsKey ("on" ) && varMapForNormalization .containsKey ("private" )) {
1178- // Check output pattern to see if it's JoinExtractFilter
1179- if (out .contains ("(Select" ) && out .contains ("(InnerJoin" ) && out .contains ("[]" )) {
1180- for (java .util .Map .Entry <String , String > e : varMapForNormalization .entrySet ()) {
1181- String base = e .getKey ();
1182- String numbered = e .getValue ();
1183- match = match .replaceAll (
1184- "\\ $" + java .util .regex .Pattern .quote (numbered .substring (1 )),
1185- java .util .regex .Matcher .quoteReplacement ("$" + base )
1186- );
1187- }
1188- }
1189- }
1190- if (name .equals ("PruneEmptyMinus" )) {
1191- match = match .replaceAll ("\\ $right_\\ d+" , java .util .regex .Matcher .quoteReplacement ("$right" ));
1192- }
11931123 sb .append (match ).append ("\n " );
11941124 sb .append ("=>\n " );
1125+ String out = transform .pattern ();
11951126 if (out .startsWith ("(ConstructEmptyValues (OutputCols $" )) {
11961127 int startIdx = "(ConstructEmptyValues (OutputCols $" .length ();
11971128 int endIdx = startIdx ;
@@ -1212,65 +1143,25 @@ else if (match.startsWith("(Union\n")) {
12121143 out = "$" + numbered ;
12131144 }
12141145 }
1215- if (match .contains ("HasZeroRows" ) && out .contains ("ConstructEmptyValues" )) {
1216- // Find the first source variable (appears before HasZeroRows in the pattern)
1217- // This handles cases where HasZeroRows is on a different source but we need the first one
1218- int hasZeroRowsIdx = match .indexOf ("(HasZeroRows $" );
1219- if (hasZeroRowsIdx >= 0 ) {
1220- // Find first variable before HasZeroRows
1221- String beforeHasZeroRows = match .substring (0 , hasZeroRowsIdx );
1222- String firstSourceVar = findFirstVar (beforeHasZeroRows );
1223- if (firstSourceVar != null ) {
1224- // Extract HasZeroRows variable
1225- int start = hasZeroRowsIdx + "(HasZeroRows $" .length ();
1226- int end = start ;
1227- while (end < match .length () && (Character .isLetterOrDigit (match .charAt (end )) || match .charAt (end ) == '_' )) end ++;
1228- String hasZeroRowsVar = match .substring (start , end );
1229- // If they differ, ensure output uses first source variable
1230- if (!hasZeroRowsVar .equals (firstSourceVar )) {
1231- out = out .replaceAll ("(OutputCols \\ $)[a-zA-Z_][a-zA-Z0-9_]*" , "$1" + firstSourceVar );
1232- } else if (match .contains ("$left" )) {
1233- // Original logic: if HasZeroRows is on left, use left variable
1234- int leftIdx = match .indexOf ("$left" );
1235- if (leftIdx >= 0 ) {
1236- start = leftIdx + 1 ;
1237- end = start ;
1238- while (end < match .length () && (Character .isLetterOrDigit (match .charAt (end )) || match .charAt (end ) == '_' )) end ++;
1239- String leftVar = match .substring (start , end );
1240- out = out .replaceAll ("(OutputCols \\ $)[a-zA-Z_][a-zA-Z0-9_]*" , "$1" + leftVar );
1241- }
1242- }
1243- }
1146+ if (match .contains ("HasZeroRows" ) && match .contains ("$left" ) && out .contains ("ConstructEmptyValues" )) {
1147+ int leftIdx = match .indexOf ("$left" );
1148+ if (leftIdx >= 0 ) {
1149+ int start = leftIdx + 1 ;
1150+ int end = start ;
1151+ while (end < match .length () && (Character .isLetterOrDigit (match .charAt (end )) || match .charAt (end ) == '_' )) end ++;
1152+ String leftVar = match .substring (start , end );
1153+ out = out .replaceAll ("(OutputCols \\ $)[a-zA-Z_][a-zA-Z0-9_]*" , "$1" + leftVar );
12441154 }
12451155 }
1246- java .util .Map <String , String > varMap = varMapForNormalization ;
1156+ java .util .Map <String , String > varMap = extractNumberedVarMap ( match ) ;
12471157 if (!varMap .isEmpty ()) {
1248- // Check if this is JoinExtractFilter pattern: Select wrapping InnerJoin with []
1249- // Distinguish from JoinCommute which has ExtractBoundConditions
1250- boolean isJoinExtractFilterPattern = out .contains ("(Select" ) &&
1251- out .contains ("(InnerJoin" ) && out .contains ("[]" ) &&
1252- match .startsWith ("(InnerJoin" ) &&
1253- varMap .containsKey ("left" ) && varMap .containsKey ("right" ) &&
1254- varMap .containsKey ("on" ) && varMap .containsKey ("private" );
1255- if (isJoinExtractFilterPattern ) {
1256- // Normalize output pattern (match already appended, so only normalize output)
1257- for (java .util .Map .Entry <String , String > e : varMap .entrySet ()) {
1258- String base = e .getKey ();
1259- String numbered = e .getValue ();
1260- out = out .replaceAll (
1261- "\\ $" + java .util .regex .Pattern .quote (numbered .substring (1 )),
1262- java .util .regex .Matcher .quoteReplacement ("$" + base )
1263- );
1264- }
1265- } else {
1266- for (java .util .Map .Entry <String , String > e : varMap .entrySet ()) {
1267- String base = e .getKey ();
1268- String numbered = e .getValue ();
1269- out = out .replaceAll (
1270- "\\ $" + java .util .regex .Pattern .quote (base ) + "(?![_0-9])" ,
1271- java .util .regex .Matcher .quoteReplacement (numbered )
1272- );
1273- }
1158+ for (java .util .Map .Entry <String , String > e : varMap .entrySet ()) {
1159+ String base = e .getKey ();
1160+ String numbered = e .getValue ();
1161+ out = out .replaceAll (
1162+ "\\ $" + java .util .regex .Pattern .quote (base ) + "(?![_0-9])" ,
1163+ java .util .regex .Matcher .quoteReplacement (numbered )
1164+ );
12741165 }
12751166 }
12761167 if (name .equals ("PruneEmptyProject" )) {
0 commit comments