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

Add support max_identifier_length session variable #20999

Merged
merged 13 commits into from
Aug 8, 2023
27 changes: 23 additions & 4 deletions src/sql-lexer/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ static ALLOCATOR: LockedAllocator<FreeListAllocator> =
#[wasm_bindgen(typescript_custom_section)]
const LEX_TS_DEF: &'static str = r#"export function lex(query: string): PosToken[];"#;

// Maximum allowed identifier length in bytes.
const MAX_IDENTIFIER_LENGTH: usize = 255;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct LexerError {
/// The error message.
Expand Down Expand Up @@ -210,7 +213,7 @@ fn lex_inner(query: &str) -> Result<Vec<PosToken>, LexerError> {
'\'' => Token::String(lex_string(buf)?),
'x' | 'X' if buf.consume('\'') => Token::HexString(lex_string(buf)?),
'e' | 'E' if buf.consume('\'') => lex_extended_string(buf)?,
'A'..='Z' | 'a'..='z' | '_' | '\u{80}'..=char::MAX => lex_ident(buf),
'A'..='Z' | 'a'..='z' | '_' | '\u{80}'..=char::MAX => lex_ident(buf)?,
'"' => lex_quoted_ident(buf)?,
'0'..='9' => lex_number(buf)?,
'.' if matches!(buf.peek(), Some('0'..='9')) => lex_number(buf)?,
Expand Down Expand Up @@ -266,14 +269,23 @@ fn lex_multiline_comment(buf: &mut LexBuf) -> Result<(), LexerError> {
bail!(pos, "unterminated multiline comment")
}

fn lex_ident(buf: &mut LexBuf) -> Token {
fn lex_ident(buf: &mut LexBuf) -> Result<Token, LexerError> {
buf.prev();
let word = buf.take_while(
|ch| matches!(ch, 'A'..='Z' | 'a'..='z' | '0'..='9' | '$' | '_' | '\u{80}'..=char::MAX),
);
match word.parse() {
Ok(kw) => Token::Keyword(kw),
Err(_) => Token::Ident(word.to_lowercase()),
Ok(kw) => Ok(Token::Keyword(kw)),
Err(_) => {
if word.len() > MAX_IDENTIFIER_LENGTH {
let pos = buf.pos() - 1;
bail!(
pos,
"identifier length exceeds {MAX_IDENTIFIER_LENGTH} bytes"
)
}
Ok(Token::Ident(word.to_lowercase()))
}
}
}

Expand All @@ -289,6 +301,13 @@ fn lex_quoted_ident(buf: &mut LexBuf) -> Result<Token, LexerError> {
None => bail!(pos, "unterminated quoted identifier"),
}
}
if s.len() > MAX_IDENTIFIER_LENGTH {
let pos = buf.pos() - 1;
bail!(
pos,
"identifier length exceeds {MAX_IDENTIFIER_LENGTH} bytes"
)
}
Ok(Token::Ident(s))
}

Expand Down
13 changes: 13 additions & 0 deletions src/sql/src/session/vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,14 @@ pub const MAX_QUERY_RESULT_SIZE: ServerVar<u32> = ServerVar {
internal: false,
};

pub const MAX_IDENTIFIER_LENGTH: ServerVar<u32> = ServerVar {
name: UncasedStr::new("max_identifier_length"),
// 1 GiB
value: &255,
sthm marked this conversation as resolved.
Show resolved Hide resolved
description: "The maximum length of object identifiers in bytes (PostgreSQL).",
internal: false,
};

/// The logical compaction window for builtin tables and sources that have the
/// `retained_metrics_relation` flag set.
///
Expand Down Expand Up @@ -1403,6 +1411,7 @@ impl SessionVars {
&ENABLE_CARDINALITY_ESTIMATES,
)
.with_var(&MAX_QUERY_RESULT_SIZE)
.with_var(&MAX_IDENTIFIER_LENGTH)
}

fn with_var<V>(mut self, var: &'static ServerVar<V>) -> Self
Expand Down Expand Up @@ -1560,6 +1569,10 @@ impl SessionVars {
Err(VarError::ReadOnlyParameter(MZ_VERSION_NAME.as_str()))
} else if name == IS_SUPERUSER_NAME {
Err(VarError::ReadOnlyParameter(IS_SUPERUSER_NAME.as_str()))
} else if name == MAX_IDENTIFIER_LENGTH.name {
Err(VarError::ReadOnlyParameter(
MAX_IDENTIFIER_LENGTH.name.as_str(),
))
} else {
self.vars
.get_mut(name)
Expand Down
78 changes: 78 additions & 0 deletions test/sqllogictest/id_length.slt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright Materialize, Inc. and contributors. All rights reserved.
#
# Use of this software is governed by the Business Source License
# included in the LICENSE file at the root of this repository.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0.

# Test that cluster ids aren't reused.

mode cockroach

# Requires stable ids
reset-server


statement error db error: ERROR: identifier length exceeds 255 bytes
SELECT 1 AS tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong

statement error db error: ERROR: identifier length exceeds 255 bytes
SELECT 1 AS "tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE CLUSTER REPLICA c.tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE CLUSTER tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong SIZE = 'small'

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE CONNECTION tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong (BROKER 'localhost')

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE DATABASE tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE INDEX tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE MATERIALIZED VIEW tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong AS SELECT 1

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE MATERIALIZED VIEW mv AS SELECT 1 AS tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE ROLE tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE SCHEMA tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE SECRET tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong AS 'secret'

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE TABLE tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong(i INT)

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE TABLE t(tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong INT)

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE TYPE tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong AS LIST (ELEMENT TYPE = int4);

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE VIEW tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong AS SELECT 1

statement error db error: ERROR: identifier length exceeds 255 bytes
CREATE VIEW v AS SELECT 1 AS tooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong

query T
SHOW max_identifier_length
----
255

statement error db error: ERROR: parameter "max_identifier_length" cannot be changed
SET max_identifier_length = 42

statement error db error: ERROR: parameter "max_identifier_length" cannot be changed
SET max_identifier_length = 1024
1 change: 1 addition & 0 deletions test/testdrive/session.td
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ max_clusters 10 "The maximum number
max_connections 1000 "The maximum number of concurrent connections (Materialize)."
max_credit_consumption_rate 1024 "The maximum rate of credit consumption in a region. Credits are consumed based on the size of cluster replicas in use (Materialize)."
max_databases 1000 "The maximum number of databases in the region (Materialize)."
max_identifier_length 255 "The maximum length of object identifiers in bytes (PostgreSQL)."
max_materialized_views 100 "The maximum number of materialized views in the region, across all schemas (Materialize)."
max_objects_per_schema 1000 "The maximum number of objects in a schema (Materialize)."
max_query_result_size 1073741824 "The maximum size in bytes for a single query's result (Materialize)."
Expand Down