You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "huntersjm (JIRA)" <ji...@apache.org> on 2015/12/09 05:00:13 UTC

[jira] [Created] (CALCITE-1009) parse sql error, Concurrent-access Anomalies

huntersjm created CALCITE-1009:
----------------------------------

             Summary: parse sql error, Concurrent-access Anomalies
                 Key: CALCITE-1009
                 URL: https://issues.apache.org/jira/browse/CALCITE-1009
             Project: Calcite
          Issue Type: Bug
         Environment: Concurrent-access Anomalies
            Reporter: huntersjm
            Assignee: Julian Hyde


When I use drill, I found a bug when calcite parsing sql.
in org.apache.calcite.rex.RexLocalRef, there is a method named createName(int index), when this method is called distributed, you find that you're not, NAMES may not be {$0 $1 .... $n}, but {$0...$29,$30...$59,$30...}
NAMES is SelfPopulatingList.class liked Thread-safe list, but unfortunately it's Thread-unsafe list, although addAll() has a lock, this method is Thread-safe, but in method get(int index)
{noformat}
@Override public String get(int index) {
      for (;;) {
        try {
          return super.get(index);
        } catch (IndexOutOfBoundsException e) {
          if (index < 0) {
            throw new IllegalArgumentException();
          }
          addAll(
              fromTo(
                  prefix, size(), Math.max(index + 1, size() * 2)));
        }
      }
    }
{noformat}
method fromTo() is not thread-safe, so it get error. So as you can see, {$30...$59} is added repeatedly.

bugfix:
There are several ways to solve this bug.
one is, add lock before addAll(), seemed like
{noformat}
@Override public String get(int index) {
      for (;;) {
        try {
          return super.get(index);
        } catch (IndexOutOfBoundsException e) {
          if (index < 0) {
            throw new IllegalArgumentException();
          }
/*********lock************/
          addAll(
              fromTo(
                  prefix, size(), Math.max(index + 1, size() * 2)));
        }
/*********unlock************/
      }
    }
{noformat}
But there is over design, catch(e) is not good.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)