Skip to content

Commit 1ea53a2

Browse files
committed
Bug#29870832 : X DEVAPI PATH OPERATOR '->>' HANDLED INCORRECTLY
1 parent 3bacbc4 commit 1ea53a2

File tree

3 files changed

+122
-82
lines changed

3 files changed

+122
-82
lines changed

cdk/parser/expr_parser.cc

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -476,15 +476,15 @@ bool Expr_parser_base::parse_schema_ident(Token::Type (*types)[2])
476476
}
477477

478478

479-
void Expr_parser_base::parse_column_ident(Path_prc *prc)
479+
void Expr_parser_base::parse_column_ident(Processor *prc)
480480
{
481481
if (!parse_schema_ident())
482482
parse_error("Expected a column identifier");
483483
parse_column_ident1(prc);
484484
}
485485

486486

487-
void Expr_parser_base::parse_column_ident1(Path_prc *prc)
487+
void Expr_parser_base::parse_column_ident1(Processor *prc)
488488
{
489489
/*
490490
Note: at this point we assume that an (possibly schema qualified) identifier
@@ -512,8 +512,27 @@ void Expr_parser_base::parse_column_ident1(Path_prc *prc)
512512
m_col_ref.set(table->name());
513513
}
514514

515-
if (consume_token(Token::ARROW) || consume_token(Token::ARROW2))
515+
auto t = peek_token();
516+
517+
Safe_prc<Processor> sprc(prc);
518+
519+
if (t && (t->get_type() == Token::ARROW || t->get_type() == Token::ARROW2))
516520
{
521+
Safe_prc<cdk::Expr_processor::Args_prc> args = nullptr;
522+
if(t->get_type() == Token::ARROW2)
523+
{
524+
Table_ref json_unquote;
525+
json_unquote.set("JSON_UNQUOTE");
526+
args =sprc->scalar()->call(json_unquote);
527+
args->list_begin();
528+
//Will override previous processor, so from now on, this will be the one
529+
//used
530+
sprc = args->list_el();
531+
}
532+
533+
consume_token();
534+
535+
cdk::Doc_path_storage path;
517536

518537
if (Token_base::cur_token_type_in({ Token::QSTRING, Token::QQSTRING }))
519538
{
@@ -522,16 +541,23 @@ void Expr_parser_base::parse_column_ident1(Path_prc *prc)
522541
It last = toks.end();
523542
Expr_parser_base path_parser(first, last, m_parser_mode);
524543
// TODO: Translate parse errors
525-
path_parser.parse_document_field(prc, true);
544+
path_parser.parse_document_field(&path, true);
526545
if (first != last)
527546
parse_error("Unexpected characters in a quoted path component");
528547
}
529548
else
530549
{
531-
parse_document_field(prc, true);
550+
parse_document_field(&path, true);
532551
}
533-
}
534552

553+
sprc->scalar()->ref(m_col_ref,&path);
554+
555+
args->list_end();
556+
}
557+
else
558+
{
559+
sprc->scalar()->ref(m_col_ref,nullptr);
560+
}
535561
}
536562

537563

@@ -1108,13 +1134,13 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
11081134
if (!prc)
11091135
prc = stored.reset(new Stored_any());
11101136

1111-
Safe_prc<Processor::Scalar_prc> sprc(prc->scalar());
1137+
Safe_prc<Processor> sprc(prc);
11121138

11131139
// parameters, nullary operators, CAST
11141140

11151141
if (consume_token(Token::COLON))
11161142
{
1117-
sprc->param(consume_token_throw(
1143+
sprc->scalar()->param(consume_token_throw(
11181144
Token::WORD,
11191145
"Expected parameter name after ':'"
11201146
).get_text());
@@ -1123,12 +1149,12 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
11231149

11241150
if (consume_token(Op::STAR))
11251151
{
1126-
sprc->op(Op::name(Op::STAR));
1152+
sprc->scalar()->op(Op::name(Op::STAR));
11271153
// NOTE: arguments processor is ignored as there are no arguments
11281154
return stored.release();
11291155
}
11301156

1131-
if (parse_cast(sprc))
1157+
if (parse_cast(prc->scalar()))
11321158
{
11331159
return stored.release();
11341160
}
@@ -1153,21 +1179,21 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
11531179
break;
11541180
}
11551181
// otherwise report as unary operator
1156-
argsp = sprc->op(Op::name(op));
1182+
argsp = sprc->scalar()->op(Op::name(op));
11571183
break;
11581184
}
11591185

11601186
case Op::NEG:
11611187
consume_token();
1162-
argsp = sprc->op(Op::name(Op::NEG));
1188+
argsp = sprc->scalar()->op(Op::name(Op::NEG));
11631189
break;
11641190
case Op::NOT:
11651191
consume_token();
1166-
argsp = sprc->op(Op::name(Op::NOT));
1192+
argsp = sprc->scalar()->op(Op::name(Op::NOT));
11671193
break;
11681194
case Op::BITNEG:
11691195
consume_token();
1170-
argsp = sprc->op(Op::name(Op::BITNEG));
1196+
argsp = sprc->scalar()->op(Op::name(Op::BITNEG));
11711197
break;
11721198

11731199
default:
@@ -1195,13 +1221,13 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
11951221
{
11961222

11971223
case Keyword::L_NULL:
1198-
sprc->val()->null();
1224+
sprc->scalar()->val()->null();
11991225
consume_token();
12001226
return stored.release();
12011227

12021228
case Keyword::L_TRUE:
12031229
case Keyword::L_FALSE:
1204-
sprc->val()->yesno(Keyword::L_TRUE == kw);
1230+
sprc->scalar()->val()->yesno(Keyword::L_TRUE == kw);
12051231
consume_token();
12061232
return stored.release();
12071233

@@ -1219,44 +1245,44 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
12191245
case Token::QSTRING:
12201246
if (m_strings_as_blobs)
12211247
{
1222-
sprc->val()->value(
1248+
sprc->scalar()->val()->value(
12231249
cdk::TYPE_BYTES, Format_info(), consume_token()->get_bytes()
12241250
);
12251251
}
12261252
else
1227-
sprc->val()->str(consume_token()->get_text());
1253+
sprc->scalar()->val()->str(consume_token()->get_text());
12281254
return stored.release();
12291255

12301256
case Token::NUMBER:
12311257
{
12321258
double val = strtod(consume_token()->get_utf8());
1233-
sprc->val()->num(neg ? -val : val);
1259+
sprc->scalar()->val()->num(neg ? -val : val);
12341260
return stored.release();
12351261
}
12361262

12371263
case Token::INTEGER:
12381264
if (neg)
12391265
{
12401266
int64_t val = strtoi(consume_token()->get_utf8());
1241-
sprc->val()->num(-val);
1267+
sprc->scalar()->val()->num(-val);
12421268
}
12431269
else
12441270
{
12451271
uint64_t val = strtoui(consume_token()->get_utf8());
1246-
sprc->val()->num(val);
1272+
sprc->scalar()->val()->num(val);
12471273
}
12481274
return stored.release();
12491275

12501276
case Token::HEX:
12511277
if (neg)
12521278
{
12531279
int64_t val = strtoi(consume_token()->get_utf8(), 16);
1254-
sprc->val()->num(-val);
1280+
sprc->scalar()->val()->num(-val);
12551281
}
12561282
else
12571283
{
12581284
uint64_t val = strtoui(consume_token()->get_utf8(), 16);
1259-
sprc->val()->num(val);
1285+
sprc->scalar()->val()->num(val);
12601286
}
12611287
return stored.release();
12621288

@@ -1315,7 +1341,7 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
13151341
{
13161342
assert(m_col_ref.table());
13171343

1318-
if (parse_function_call(*m_col_ref.table(), sprc))
1344+
if (parse_function_call(*m_col_ref.table(), sprc.scalar()))
13191345
return stored.release();
13201346
}
13211347

@@ -1324,8 +1350,6 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
13241350
a column identifier, possibly followed by a path (in TABLE mode).
13251351
*/
13261352

1327-
cdk::Doc_path_storage path;
1328-
13291353
if (Parser_mode::TABLE == m_parser_mode)
13301354
{
13311355
/*
@@ -1341,8 +1365,8 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
13411365
the processor.
13421366
*/
13431367

1344-
parse_column_ident1(&path);
1345-
sprc->ref(m_col_ref, path.is_empty() ? NULL : &path);
1368+
parse_column_ident1(prc);
1369+
13461370
return stored.release();
13471371
}
13481372

@@ -1363,6 +1387,8 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
13631387
field.
13641388
*/
13651389

1390+
cdk::Doc_path_storage path;
1391+
13661392
if (m_col_ref.table() && m_col_ref.table()->schema())
13671393
{
13681394
parse_document_field(
@@ -1380,7 +1406,7 @@ Expression* Expr_parser_base::parse_atomic(Processor *prc)
13801406
parse_document_field(&path, true);
13811407
}
13821408

1383-
sprc->ref(path);
1409+
sprc->scalar()->ref(path);
13841410

13851411
return stored.release();
13861412
}

cdk/parser/expr_parser.h

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -803,8 +803,8 @@ class Expr_parser_base
803803
);
804804

805805
bool parse_schema_ident(Token::Type (*types)[2] = NULL);
806-
void parse_column_ident(Path_prc*);
807-
void parse_column_ident1(Path_prc*);
806+
void parse_column_ident(Processor *);
807+
void parse_column_ident1(Processor*);
808808
bool get_ident(string&);
809809

810810
void parse_document_field(Path_prc*, bool prefix = false);
@@ -972,54 +972,6 @@ class Projection_parser
972972

973973
};
974974

975-
/*
976-
Class Used to parse Table fields.
977-
Format: table.column->@.field.arr[]
978-
*/
979-
980-
class Table_field_parser
981-
: public cdk::api::Column_ref
982-
, public cdk::Doc_path
983-
{
984-
parser::Column_ref m_col;
985-
cdk::Doc_path_storage m_path;
986-
987-
public:
988-
989-
Table_field_parser(bytes table_field)
990-
{
991-
Tokenizer toks(table_field);
992-
993-
It begin = toks.begin();
994-
const It end = toks.end();
995-
996-
Expr_parser_base parser(begin, end, Parser_mode::TABLE);
997-
parser.parse_column_ident(&m_path);
998-
m_col = parser.m_col_ref;
999-
}
1000-
1001-
const cdk::string name() const
1002-
{
1003-
return m_col.name();
1004-
}
1005-
1006-
const cdk::api::Table_ref *table() const
1007-
{
1008-
return m_col.table();
1009-
}
1010-
1011-
bool has_path() const
1012-
{
1013-
return !m_path.is_empty();
1014-
}
1015-
1016-
void process(Processor &prc) const
1017-
{
1018-
m_path.process(prc);
1019-
}
1020-
1021-
};
1022-
1023975

1024976
/*
1025977
This class acts as cdk::Doc_path object taking path data from a string
@@ -1616,6 +1568,56 @@ Expression* Expr_parser_base::parse(Start start, Processor *prc)
16161568
}
16171569

16181570

1571+
/*
1572+
Class Used to parse Table fields.
1573+
Format: table.column->@.field.arr[]
1574+
*/
1575+
1576+
class Table_field_parser
1577+
: public cdk::api::Column_ref
1578+
, public cdk::Doc_path
1579+
{
1580+
parser::Column_ref m_col;
1581+
Stored_any m_path;
1582+
1583+
public:
1584+
1585+
Table_field_parser(bytes table_field)
1586+
{
1587+
Tokenizer toks(table_field);
1588+
1589+
It begin = toks.begin();
1590+
const It end = toks.end();
1591+
1592+
Expr_parser_base parser(begin, end, Parser_mode::TABLE);
1593+
parser.parse_column_ident(&m_path);
1594+
m_col = parser.m_col_ref;
1595+
}
1596+
1597+
const cdk::string name() const
1598+
{
1599+
return m_col.name();
1600+
}
1601+
1602+
const cdk::api::Table_ref *table() const
1603+
{
1604+
return m_col.table();
1605+
}
1606+
1607+
bool has_path() const
1608+
{
1609+
return m_path.m_scalar && !m_path.m_scalar->m_doc_path.is_empty();
1610+
}
1611+
1612+
void process(Processor &prc) const
1613+
{
1614+
if(m_path.m_scalar)
1615+
m_path.m_scalar->m_doc_path.process(prc);
1616+
}
1617+
1618+
};
1619+
1620+
16191621
} // parser
16201622

16211623
#endif

0 commit comments

Comments
 (0)