Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing quoted strings to methods removes quotes. #6250

Closed
12 tasks
mmacfadden opened this issue Jun 3, 2016 · 9 comments
Closed
12 tasks

Passing quoted strings to methods removes quotes. #6250

mmacfadden opened this issue Jun 3, 2016 · 9 comments
Assignees
Labels
Milestone

Comments

@mmacfadden
Copy link
Contributor

Expected behavior and actual behavior

When passing a quoted string to a function the function should use the quoted version of the string. Instead the quotes seem to be stripped.

Steps to reproduce the problem

Run the following SQL.

DROP CLASS test;
CREATE CLASS test;
CREATE PROPERTY test.id String;
CREATE PROPERTY test.value String;

INSERT INTO test SET id = "1", value = "Test 1: ";
UPDATE test SET value = value.append("\"double quotes\"") WHERE id = "1";

INSERT INTO test SET id = "2", value = "Test 2: ";
UPDATE test SET value = value.append("'single quotes'") WHERE id = "2";

INSERT INTO test SET id = "3", value = "Test 3: ";
UPDATE test SET value = value.append("\"mixed quotes'") WHERE id = "3";

INSERT INTO test SET id = "4", value = "Test 4: ";
UPDATE test SET value = value.append("\"one quote") WHERE id = "4";

INSERT INTO test SET id = "5", value = "Test 5: ";
UPDATE test SET value = value.append("\"nested \"quotes\" in quotes\"") WHERE id = "5";

SELECT * FROM test;

Output:

Test 1: double quotes

  • Both surrounding quotes are stripped

Test 2: single quotes

  • Both surrounding quotes are stripped

Test 3: "mixed quotes'

  • Both quotes left

Test 4: "one quote

  • preceding quote intact

Test 5: nested "quotes" in quotes

  • Outer quotes are stripped, inner quotes are left.

It seems that this might be a parser issue given the sensitivity to matched quotes and the fact that only outer quotes are being stripped. This is not unique to the append method, it also was noted in "right", and "substring" as well.

Also, when doing an INSERT, the quotes seem to be just fine, so it appears to be related to quoted strings passed to functions.

Important Questions

None

Runninng Mode

  • Embedded, using PLOCAL access mode
  • [ X] Embedded, using MEMORY access mode
  • Remote

Misc

  • I have a distributed setup with multiple servers. How many?
  • I'm using the Enterprise Edition

OrientDB Version

  • v2.0.x - Please specify last number:
  • v2.1.x - Please specify last number:
  • [X ] v2.2.x - Please specify last number: 2.2.0

Operating System

  • Linux
  • [ X] MacOSX
  • Windows
  • Other Unix
  • Other, name?

Java Version

  • 6
  • 7
  • [ X] 8
@luigidellaquila luigidellaquila self-assigned this Jun 3, 2016
@mmacfadden
Copy link
Contributor Author

I have done some debugging. The issue seems to an issue in the OSQLMethodRuntime class.

Looking at the OSQLFilterItemField.transformValue class on line 129, there is the following code:

public Object transformValue(final OIdentifiable iRecord, final OCommandContext iContext, Object ioResult) {
    if (ioResult != null && operationsChain != null) {
      // APPLY OPERATIONS FOLLOWING THE STACK ORDER
      OSQLMethodRuntime method = null;

      for (OPair<OSQLMethodRuntime, Object[]> op : operationsChain) {
        method = op.getKey();

        // DON'T PASS THE CURRENT RECORD TO FORCE EVALUATING TEMPORARY RESULT
        method.setParameters(op.getValue(), true);

        ioResult = method.execute(ioResult, iRecord, ioResult, iContext);
      }
    }

    return ioResult;
  }

Specifically on line 138 method.setParameters() gets call. Then later on line 140 method.execute gets calls. op.getValue() will return an array with a string in it like this[""quoted""]. Note the double quotes, and also note that really it is a string containing a double quoted string. Looking in OSQLMethodRuntime.setParameters, on line 184 there is the following code, which is trying to preprocess all of the parameters for the method call, in this case "append":

final Object v = OSQLHelper.parseValue(null, null, iParameters[i].toString(), null);

This works it way through the OSQLhelper class and ultimately winds up on line 103, where this code is:

fieldValue = OIOUtils.getStringContent(iValue);

The OIOUtils.getStringContent will strip the enclosing strings. So the parameter is changed from ""quoted"" to "quoted". So we have unwrapped one set of quotes. This chain of code returns all the way up back to the OSQLFilterItemField.transformValue, and we move on to line 140 where we call method.execute. In the OSQLMethodRuntime.execute method on line 121, we see the following code:

else if (configuredParameters[i] instanceof String) {
  if (configuredParameters[i].toString().startsWith("\"") || configuredParameters[i].toString().startsWith("'"))
    runtimeParameters[i] = OIOUtils.getStringContent(configuredParameters[i]);
}

As you can see we wind up calling OIOUtils.getStringContent AGAIN. This will now transform the parameter from ["quoted"] to [quoted]. The string now contains no quotes.

Is it possible that the last code block ahead on line 121 is redundant? It seems like the unwrapping of quotes already happens during setParameters, so do we need to do it again during the execute phase? Either way, there is clearly some incorrect interplay between the two calls to *OIOUtils.getStringContent *.

@luigidellaquila
Copy link
Member

Hi @mmacfadden

Thank you very much for the detailed info.
I'll work on it asap

Thanks

Luigi

@mmacfadden
Copy link
Contributor Author

Any luck here? Of all the issues, this is the biggest show stopper for us, since it seems that you can not insert any data that itself is wrapped in quotes. If you have any ideas, I would be more than happy to work on a PR.

@luigidellaquila
Copy link
Member

Hi @mmacfadden

it's trickier than expected, I tried to comment the first method that removes the back-ticks, but there is another one in the chain that does the same, so actually two couples of back-ticks will be removed, if present.

I hope I'll be able to give you a fix soon

Thanks

Luigi

@mmacfadden
Copy link
Contributor Author

@luigidellaquila I will try to take a second pass and help you out this weekend.

@mmacfadden
Copy link
Contributor Author

Ok I see now that OIOUtils.getStringContent() is being called three times. It gets called via:

  1. OSQLMethodRuntime.setParameters(Object[], boolean)
  2. OSQLMethodRuntime.execute(Object, OIdentifiable, Object, OCommandContext)
  3. OSQLMethodAppend.execute(Object, OIdentifiable, OCommandContext, Object, Object[])

Se we are unquoting when we set parameters, when we execute the method (in the runtime), and then the specific method is unwrapping them as well.

The question is where should we assume this takes place. If the runtime is going to unquote them when setting the parameters ( number 1), do we need to do number 2 or number 3?

@mmacfadden
Copy link
Contributor Author

@luigidellaquila Just as a small update. I am still able to reproduce this error in 3.x.

@luigidellaquila
Copy link
Member

Hi @mmacfadden

I pushed a fix on both 3.0 and 3.1 branches

Thanks

Luigi

@mmacfadden
Copy link
Contributor Author

@luigidellaquila Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants