mirror of https://github.com/apache/cassandra
Merge b303529aec into 10557d7ffe
This commit is contained in:
commit
ca70247d0b
|
|
@ -116,43 +116,6 @@ class Cql3ParsingRuleSet(CqlParsingRuleSet):
|
||||||
'overlap_inclusion_method'
|
'overlap_inclusion_method'
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def escape_value(cls, value):
|
|
||||||
if value is None:
|
|
||||||
return 'NULL' # this totally won't work
|
|
||||||
if isinstance(value, bool):
|
|
||||||
value = str(value).lower()
|
|
||||||
elif isinstance(value, float):
|
|
||||||
return '%f' % value
|
|
||||||
elif isinstance(value, int):
|
|
||||||
return str(value)
|
|
||||||
return "'%s'" % value.replace("'", "''")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def escape_name(cls, name):
|
|
||||||
if name is None:
|
|
||||||
return 'NULL'
|
|
||||||
return "'%s'" % name.replace("'", "''")
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def dequote_name(name):
|
|
||||||
name = name.strip()
|
|
||||||
if name == '':
|
|
||||||
return name
|
|
||||||
if name[0] == '"' and name[-1] == '"':
|
|
||||||
return name[1:-1].replace('""', '"')
|
|
||||||
else:
|
|
||||||
return name.lower()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def dequote_value(cqlword):
|
|
||||||
cqlword = cqlword.strip()
|
|
||||||
if cqlword == '':
|
|
||||||
return cqlword
|
|
||||||
if cqlword[0] == "'" and cqlword[-1] == "'":
|
|
||||||
cqlword = cqlword[1:-1].replace("''", "'")
|
|
||||||
return cqlword
|
|
||||||
|
|
||||||
|
|
||||||
CqlRuleSet = Cql3ParsingRuleSet()
|
CqlRuleSet = Cql3ParsingRuleSet()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,43 @@ class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
|
||||||
tokens = self.cql_massage_tokens(tokens)
|
tokens = self.cql_massage_tokens(tokens)
|
||||||
return self.parse(startsymbol, tokens, init_bindings={'*SRC*': text})
|
return self.parse(startsymbol, tokens, init_bindings={'*SRC*': text})
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dequote_value(cqlword):
|
||||||
|
cqlword = cqlword.strip()
|
||||||
|
if cqlword == '':
|
||||||
|
return cqlword
|
||||||
|
if cqlword[0] == "'" and cqlword[-1] == "'":
|
||||||
|
cqlword = cqlword[1:-1].replace("''", "'")
|
||||||
|
return cqlword
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dequote_name(name):
|
||||||
|
name = name.strip()
|
||||||
|
if name == '':
|
||||||
|
return name
|
||||||
|
if name[0] == '"' and name[-1] == '"':
|
||||||
|
return name[1:-1].replace('""', '"')
|
||||||
|
else:
|
||||||
|
return name.lower()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def escape_value(value):
|
||||||
|
if value is None:
|
||||||
|
return 'NULL' # this totally won't work
|
||||||
|
if isinstance(value, bool):
|
||||||
|
value = str(value).lower()
|
||||||
|
elif isinstance(value, float):
|
||||||
|
return '%f' % value
|
||||||
|
elif isinstance(value, int):
|
||||||
|
return str(value)
|
||||||
|
return "'%s'" % value.replace("'", "''")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def escape_name(name):
|
||||||
|
if name is None:
|
||||||
|
return 'NULL'
|
||||||
|
return '"%s"' % name.replace('"', '""')
|
||||||
|
|
||||||
def cql_whole_parse_tokens(self, toklist, srcstr=None, startsymbol='Start'):
|
def cql_whole_parse_tokens(self, toklist, srcstr=None, startsymbol='Start'):
|
||||||
return self.whole_match(startsymbol, toklist, srcstr=srcstr)
|
return self.whole_match(startsymbol, toklist, srcstr=srcstr)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ class SaferScannerBase(re.Scanner):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def subpat(cls, phrase, flags):
|
def subpat(cls, phrase, flags):
|
||||||
|
# pylint: disable=no-member
|
||||||
return cls.scrub_sub(re.sre_parse.parse(phrase, flags), flags)
|
return cls.scrub_sub(re.sre_parse.parse(phrase, flags), flags)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -38,6 +39,7 @@ class SaferScannerBase(re.Scanner):
|
||||||
seqtypes = (type(()), type([]))
|
seqtypes = (type(()), type([]))
|
||||||
for op, arg in sub.data:
|
for op, arg in sub.data:
|
||||||
if type(arg) in seqtypes:
|
if type(arg) in seqtypes:
|
||||||
|
# pylint: disable=no-member
|
||||||
arg = [cls.scrub_sub(a, flags) if isinstance(a, re.sre_parse.SubPattern) else a
|
arg = [cls.scrub_sub(a, flags) if isinstance(a, re.sre_parse.SubPattern) else a
|
||||||
for a in arg]
|
for a in arg]
|
||||||
if op in (BRANCH, SUBPATTERN):
|
if op in (BRANCH, SUBPATTERN):
|
||||||
|
|
@ -49,6 +51,7 @@ class SaferScannerBase(re.Scanner):
|
||||||
raise ValueError("Named captures not allowed in SaferScanner lexicon")
|
raise ValueError("Named captures not allowed in SaferScanner lexicon")
|
||||||
if sub.pattern.flags ^ flags:
|
if sub.pattern.flags ^ flags:
|
||||||
raise ValueError("RE flag setting not allowed in SaferScanner lexicon (%s)" % (bin(sub.pattern.flags),))
|
raise ValueError("RE flag setting not allowed in SaferScanner lexicon (%s)" % (bin(sub.pattern.flags),))
|
||||||
|
# pylint: disable=no-member
|
||||||
return re.sre_parse.SubPattern(sub.pattern, scrubbedsub)
|
return re.sre_parse.SubPattern(sub.pattern, scrubbedsub)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -57,6 +60,7 @@ class Py36SaferScanner(SaferScannerBase):
|
||||||
def __init__(self, lexicon, flags=0):
|
def __init__(self, lexicon, flags=0):
|
||||||
self.lexicon = lexicon
|
self.lexicon = lexicon
|
||||||
p = []
|
p = []
|
||||||
|
# pylint: disable=no-member
|
||||||
s = re.sre_parse.Pattern()
|
s = re.sre_parse.Pattern()
|
||||||
s.flags = flags
|
s.flags = flags
|
||||||
for phrase, action in lexicon:
|
for phrase, action in lexicon:
|
||||||
|
|
@ -73,6 +77,7 @@ class Py38SaferScanner(SaferScannerBase):
|
||||||
def __init__(self, lexicon, flags=0):
|
def __init__(self, lexicon, flags=0):
|
||||||
self.lexicon = lexicon
|
self.lexicon = lexicon
|
||||||
p = []
|
p = []
|
||||||
|
# pylint: disable=no-member
|
||||||
s = re.sre_parse.State()
|
s = re.sre_parse.State()
|
||||||
s.flags = flags
|
s.flags = flags
|
||||||
for phrase, action in lexicon:
|
for phrase, action in lexicon:
|
||||||
|
|
@ -89,6 +94,7 @@ class Py311SaferScanner(SaferScannerBase):
|
||||||
def __init__(self, lexicon, flags=0):
|
def __init__(self, lexicon, flags=0):
|
||||||
self.lexicon = lexicon
|
self.lexicon = lexicon
|
||||||
p = []
|
p = []
|
||||||
|
# pylint: disable=no-member
|
||||||
s = re._parser.State()
|
s = re._parser.State()
|
||||||
s.flags = flags
|
s.flags = flags
|
||||||
for phrase, action in lexicon:
|
for phrase, action in lexicon:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from .basecase import BaseTestCase
|
||||||
|
from cqlshlib.cql3handling import CqlRuleSet
|
||||||
|
|
||||||
|
|
||||||
|
class TestRuleSetUtils(BaseTestCase):
|
||||||
|
def test_dequote_value(self):
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_value("'test'"), "test")
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_value("'test''val'"), "test'val")
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_value("unquoted"), "unquoted")
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_value(""), "")
|
||||||
|
|
||||||
|
def test_dequote_name(self):
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_name('"TestName"'), "TestName")
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_name('"Test""Name"'), 'Test"Name')
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_name("LowercaseName"), "lowercasename")
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_name(""), "")
|
||||||
|
|
||||||
|
def test_escape_value(self):
|
||||||
|
self.assertEqual(CqlRuleSet.escape_value("val'with'quote"), "'val''with''quote'")
|
||||||
|
self.assertEqual(CqlRuleSet.escape_value(True), "'true'")
|
||||||
|
self.assertEqual(CqlRuleSet.escape_value(123), "123")
|
||||||
|
self.assertEqual(CqlRuleSet.escape_value(1.23), "1.230000")
|
||||||
|
self.assertEqual(CqlRuleSet.escape_value(None), "NULL")
|
||||||
|
|
||||||
|
def test_escape_name(self):
|
||||||
|
self.assertEqual(CqlRuleSet.escape_name('name"with"quote'), '"name""with""quote"')
|
||||||
|
self.assertEqual(CqlRuleSet.dequote_name(CqlRuleSet.escape_name('name"with"quote')), 'name"with"quote')
|
||||||
|
self.assertEqual(CqlRuleSet.escape_name(None), "NULL")
|
||||||
Loading…
Reference in New Issue