示例#1
0
Datum
email_le(PG_FUNCTION_ARGS)
{

	VarChar *str=PG_GETARG_VARCHAR_P(0);
	VarChar *str1=PG_GETARG_VARCHAR_P(1);

	PG_RETURN_BOOL(!is_email_gt(str, str1));
}
示例#2
0
Datum
email_cmp(PG_FUNCTION_ARGS)
{
	VarChar *str=PG_GETARG_VARCHAR_P(0);
	VarChar *str1=PG_GETARG_VARCHAR_P(1);	
	
	int result_value = 0;
	
	if(is_email_lt(str, str1)==IS_TRUE)  //<
		result_value=-1;
	else if(is_email_gt(str, str1)==IS_TRUE)  //>
		result_value=1;

	PG_RETURN_INT32(result_value);
	
}
示例#3
0
文件: nseq_io.c 项目: ergo70/nseq
Datum
rna_in_varchar (PG_FUNCTION_ARGS)
{
    VarChar *x = PG_GETARG_VARCHAR_P (0);
    char *input = VARDATA(x);
    size_t size = VARSIZE(x)-VARHDRSZ;

    PG_RETURN_NSEQ_P (make_nseq(input,size,true));
}
示例#4
0
Datum
molecule_in_varchar (PG_FUNCTION_ARGS)
{
  VarChar *x = PG_GETARG_VARCHAR_P (0);  
  char *input = VARDATA(x);
  int size = VARSIZE(x)-VARHDRSZ;
  
  PG_RETURN_MOLECULE_P (make_molecule(input,size));
}
示例#5
0
文件: nseq_io.c 项目: ergo70/nseq
Datum
dna_in_varchar (PG_FUNCTION_ARGS)
{
    VarChar *x = PG_GETARG_VARCHAR_P (0);
    char *input = VARDATA(x);
    size_t size = VARSIZE(x)-VARHDRSZ;

    //elog(INFO,"varchar %d", size);

    PG_RETURN_NSEQ_P (make_nseq(input,size,false));
}
示例#6
0
Datum verify_row_visible(PG_FUNCTION_ARGS) {
    VarChar *auths_base64 = PG_GETARG_VARCHAR_P(0);
    VarChar *vis_base64 = PG_GETARG_VARCHAR_P(1);

    authorizations_handle_t *auths = deserialize_auths(auths_base64);
    if (!auths) {
        ereport(ERROR,
                (errmsg("There was an error deserializing the "
                        "authorizations!")));

        PG_RETURN_BOOL(false);
    }

    visibility_handle_t *vis = deserialize_vis(vis_base64);
    if (!vis) {
        ereport(ERROR,
                (errmsg("There was an error deserializing the visibility!")));

        ezbake_authorizations_handle_free(auths);
        PG_RETURN_BOOL(false);
    }

    char *error = NULL;
    uint32_t permissions = ezbake_get_user_permissions(auths, vis, &error);
    if (error) {
        ereport(ERROR, (errmsg("Error evaluating permissions: %s", error)));
        ezbake_authorizations_handle_free(auths);
        ezbake_visibility_handle_free(vis);
        free(error);
        PG_RETURN_BOOL(false);
    }

    ezbake_authorizations_handle_free(auths);
    ezbake_visibility_handle_free(vis);
    bool is_authorized =
        (permissions & EZBAKE_USER_PERM_READ) &&
        (permissions & EZBAKE_USER_PERM_WRITE) &&
        (permissions & EZBAKE_USER_PERM_MANAGE_VISIBILITY);

    PG_RETURN_BOOL(is_authorized);
}
示例#7
0
Datum
email_out(PG_FUNCTION_ARGS)
{
	VarChar *str=PG_GETARG_VARCHAR_P(0);
	int len;
	char *rt;
	
	len = GET_VARSIZE(str);
	rt=palloc(len+1);
	memcpy(rt,VARDATA(str),len);
	rt[len]='\0';

	PG_RETURN_CSTRING(rt);
}
示例#8
0
/*
 * Convert a VARCHAR value to a C string.
 */
Datum
varcharout(PG_FUNCTION_ARGS)
{
	VarChar    *s = PG_GETARG_VARCHAR_P(0);
	char	   *result;
	int32		len;

	/* copy and add null term */
	len = VARSIZE(s) - VARHDRSZ;
	result = palloc(len + 1);
	memcpy(result, VARDATA(s), len);
	result[len] = '\0';

	PG_RETURN_CSTRING(result);
}
示例#9
0
Datum
email_hash(PG_FUNCTION_ARGS)
{
	VarChar *str=PG_GETARG_VARCHAR_P(0);
	char *rt;
	int32 len,hash_val=0;

	len=GET_VARSIZE(str);
	rt=palloc(len+1);
	memcpy(rt,VARDATA(str),len);
	rt[len]='\0';
	hash_val=hash_any((unsigned char*)rt,len);
	pfree(rt);

	PG_RETURN_INT32(hash_val);
}
示例#10
0
Datum get_purge_id(PG_FUNCTION_ARGS) {
    VarChar *vis_base64 = PG_GETARG_VARCHAR_P(0);
    visibility_handle_t *vis = deserialize_vis(vis_base64);
    if (!vis) {
        PG_RETURN_BOOL(false);
    }

    char *error = NULL;
    purge_info_t purge_info;
    purge_info.id = -1;
    ezbake_get_purge_info(vis, &purge_info, &error);
    if (error) {
        ereport(ERROR, (errmsg("Error getting the purge info from visibility! %s", error)));
        free(error);
    }

    ezbake_visibility_handle_free(vis);
    PG_RETURN_INT64(purge_info.id);
}
示例#11
0
/*
 * Converts a VARCHAR type to the specified size.
 *
 * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes.
 * isExplicit is true if this is for an explicit cast to varchar(N).
 *
 * Truncation rules: for an explicit cast, silently truncate to the given
 * length; for an implicit cast, raise error unless extra characters are
 * all spaces.	(This is sort-of per SQL: the spec would actually have us
 * raise a "completion condition" for the explicit cast case, but Postgres
 * hasn't got such a concept.)
 */
Datum
varchar(PG_FUNCTION_ARGS)
{
	VarChar    *source = PG_GETARG_VARCHAR_P(0);
	int32		maxlen = PG_GETARG_INT32(1);
	bool		isExplicit = PG_GETARG_BOOL(2);
	VarChar    *result;
	int32		len;
	size_t		maxmblen;
	int			i;

	len = VARSIZE(source);
	/* No work if typmod is invalid or supplied data fits it already */
	if (maxlen < (int32) VARHDRSZ || len <= maxlen)
		PG_RETURN_VARCHAR_P(source);

	/* only reach here if string is too long... */

	/* truncate multibyte string preserving multibyte boundary */
	maxmblen = pg_mbcharcliplen(VARDATA(source), len - VARHDRSZ,
								maxlen - VARHDRSZ);

	if (!isExplicit)
	{
		for (i = maxmblen; i < len - VARHDRSZ; i++)
			if (*(VARDATA(source) + i) != ' ')
				ereport(ERROR,
						(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
					  errmsg("value too long for type character varying(%d)",
							 maxlen - VARHDRSZ)));
	}

	len = maxmblen + VARHDRSZ;
	result = palloc(len);
	VARATT_SIZEP(result) = len;
	memcpy(VARDATA(result), VARDATA(source), len - VARHDRSZ);

	PG_RETURN_VARCHAR_P(result);
}
Datum HASHAPI_Hash_1_Varchar(PG_FUNCTION_ARGS)
{
    int32 num_segs;            /* number of segments  */
	VarChar    *val1;        	   /* varchar value		  */
    unsigned int targetbucket; /* 0-based             */
    int16 algorithm;  /* hashing algorithm   */
	Datum d1;
	Oid oid;
	
	/* Get number of segments */
    num_segs = PG_GETARG_INT32(0);

	/* Get hashing algoriithm */
	algorithm = PG_GETARG_INT16(1);

	/* Get the value to hash */
	val1 = PG_GETARG_VARCHAR_P(2);
	
	
	d1 = PointerGetDatum(val1);
	
	/* create a CdbHash for this hash test. */
	h = makeCdbHash(num_segs, algorithm);
	
	/* init cdb hash */
	cdbhashinit(h);
	oid = VARCHAROID;
	cdbhash(h, d1, oid);
	
	/* reduce the result hash value */
	targetbucket = cdbhashreduce(h);	
	
	
	/* Avoid leaking memory for toasted inputs */
	PG_FREE_IF_COPY(val1, 2);
	
	PG_RETURN_INT32(targetbucket); /* return target bucket (segID) */
}
示例#13
0
Datum should_purge(PG_FUNCTION_ARGS) {
    ArrayType *purge_vector = PG_GETARG_ARRAYTYPE_P(0);
    VarChar *vis_base64 = PG_GETARG_VARCHAR_P(1);

    int64 *purge_vector_data = (int64 *) ARR_DATA_PTR(purge_vector);
    visibility_handle_t *vis = deserialize_vis(vis_base64);
    if (!vis) {
        PG_RETURN_BOOL(false);
    }

    char *error = NULL;
    bool result = ezbake_should_purge(
            (int64_t *) purge_vector_data,
            (size_t) ARR_DIMS(purge_vector)[0], vis, &error);

    if (error) {
        ereport(ERROR, (errmsg("Error testing purge vectors: %s", error)));
        free(error);
        result = false;
    }

    ezbake_visibility_handle_free(vis);
    PG_RETURN_BOOL(result);
}
示例#14
0
/*
table_log_restore_table()

restore a complete table based on the logging table

parameter:
  - original table name
  - name of primary key in original table
  - logging table
  - name of primary key in logging table
  - restore table name
  - timestamp for restoring data
  - primary key to restore (only this key will be restored) (optional)
  - restore mode
    0: restore from blank table (default)
       needs a complete logging table
    1: restore from actual table backwards
  - dont create table temporarly
    0: create restore table temporarly (default)
    1: create restore table not temporarly
  return:
    not yet defined
*/
Datum table_log_restore_table(PG_FUNCTION_ARGS) {
  /* the original table name */
  char  *table_orig;
  /* the primary key in the original table */
  char  *table_orig_pkey;
  /* number columns in original table */
  int  table_orig_columns;
  /* the log table name */
  char  *table_log;
  /* the primary key in the log table (usually trigger_id) */
  /* cannot be the same then then the pkey in the original table */
  char  *table_log_pkey;
  /* number columns in log table */
  int  table_log_columns;
  /* the restore table name */
  char  *table_restore;
  /* the timestamp in past */
  Datum      timestamp = PG_GETARG_DATUM(5);
  /* the single pkey, can be null (then all keys will be restored) */
  char  *search_pkey = "";
  /* the restore method
    - 0: restore from blank table (default)
         needs a complete log table!
    - 1: restore from actual table backwards
  */
  int            method = 0;
  /* dont create restore table temporarly
    - 0: create restore table temporarly (default)
    - 1: dont create restore table temporarly
  */
  int            not_temporarly = 0;
  int            ret, results, i, number_columns;
  char           query[250 + NAMEDATALEN];	/* for getting table infos (250 chars (+ one times the length of all names) should be enough) */
  int            need_search_pkey = 0;          /* does we have a single key to restore? */
  char           *tmp, *timestamp_string, *old_pkey_string = "";
  char           *trigger_mode, *trigger_tuple, *trigger_changed;
  SPITupleTable  *spi_tuptable = NULL;          /* for saving query results */
  VarChar        *return_name;

  /* memory for dynamic query */
  int      d_query_size = 250;                  /* start with 250 bytes */
  char     *d_query;
  char     *d_query_start;

  /* memory for column names */
  int      col_query_size = 0;
  char     *col_query;
  char     *col_query_start;

  int      col_pkey = 0;

  /*
   * Some checks first...
   */

#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "start table_log_restore_table()");
#endif /* TABLE_LOG_DEBUG */

  /* does we have all arguments? */
  if (PG_ARGISNULL(0)) {
    elog(ERROR, "table_log_restore_table: missing original table name");
  }
  if (PG_ARGISNULL(1)) {
    elog(ERROR, "table_log_restore_table: missing primary key name for original table");
  }
  if (PG_ARGISNULL(2)) {
    elog(ERROR, "table_log_restore_table: missing log table name");
  }
  if (PG_ARGISNULL(3)) {
    elog(ERROR, "table_log_restore_table: missing primary key name for log table");
  }
  if (PG_ARGISNULL(4)) {
    elog(ERROR, "table_log_restore_table: missing copy table name");
  }
  if (PG_ARGISNULL(5)) {
    elog(ERROR, "table_log_restore_table: missing timestamp");
  }

  /* first check number arguments to avoid an segfault */
  if (PG_NARGS() >= 7) {
    /* if argument is given, check if not null */
    if (!PG_ARGISNULL(6)) {
      /* yes, fetch it */
      search_pkey = __table_log_varcharout((VarChar *)PG_GETARG_VARCHAR_P(6));
      /* and check, if we have an argument */
      if (strlen(search_pkey) > 0) {
        need_search_pkey = 1;
#ifdef TABLE_LOG_DEBUG
        elog(NOTICE, "table_log_restore_table: will restore a single key");
#endif /* TABLE_LOG_DEBUG */
      }
    }
  }

  /* same procedere here */
  if (PG_NARGS() >= 8) {
    if (!PG_ARGISNULL(7)) {
      method = PG_GETARG_INT32(7);
      if (method > 0) {
        method = 1;
      } else {
        method = 0;
      }
    }
  }
#ifdef TABLE_LOG_DEBUG
  if (method == 1) {
    elog(NOTICE, "table_log_restore_table: will restore from actual state backwards");
  } else {
    elog(NOTICE, "table_log_restore_table: will restore from begin forward");
  }
#endif /* TABLE_LOG_DEBUG */
  if (PG_NARGS() >= 9) {
    if (!PG_ARGISNULL(8)) {
      not_temporarly = PG_GETARG_INT32(8);
      if (not_temporarly > 0) {
        not_temporarly = 1;
      } else {
        not_temporarly = 0;
      }
    }
  }
#ifdef TABLE_LOG_DEBUG
  if (not_temporarly == 1) {
    elog(NOTICE, "table_log_restore_table: dont create restore table temporarly");
  }
#endif /* TABLE_LOG_DEBUG */
  /* get parameter */
  table_orig = __table_log_varcharout((VarChar *)PG_GETARG_VARCHAR_P(0));
  table_orig_pkey = __table_log_varcharout((VarChar *)PG_GETARG_VARCHAR_P(1));
  table_log = __table_log_varcharout((VarChar *)PG_GETARG_VARCHAR_P(2));
  table_log_pkey = __table_log_varcharout((VarChar *)PG_GETARG_VARCHAR_P(3));
  table_restore = __table_log_varcharout((VarChar *)PG_GETARG_VARCHAR_P(4));

  /* pkey of original table cannot be the same as of log table */
  if (strcmp((const char *)table_orig_pkey, (const char *)table_log_pkey) == 0) {
    elog(ERROR, "pkey of logging table cannot be the pkey of the original table: %s <-> %s", table_orig_pkey, table_log_pkey);
  }

  /* Connect to SPI manager */
  ret = SPI_connect();
  if (ret != SPI_OK_CONNECT) {
    elog(ERROR, "table_log_restore_table: SPI_connect returned %d", ret);
  }

  /* check original table */
  snprintf(query, 249, "SELECT a.attname FROM pg_class c, pg_attribute a WHERE c.relname = %s AND a.attnum > 0 AND a.attrelid = c.oid ORDER BY a.attnum", do_quote_literal(table_orig));
#ifdef TABLE_LOG_DEBUG_QUERY
  elog(NOTICE, "query: %s", query);
#endif /* TABLE_LOG_DEBUG_QUERY */
  ret = SPI_exec(query, 0);
  if (ret != SPI_OK_SELECT) {
    elog(ERROR, "could not check relation: %s", table_orig);
  }
  if (SPI_processed > 0) {
    table_orig_columns = SPI_processed;
  } else {
    elog(ERROR, "could not check relation: %s", table_orig);
  }
  /* check pkey in original table */
  snprintf(query, 249, "SELECT a.attname FROM pg_class c, pg_attribute a WHERE c.relname=%s AND c.relkind='r' AND a.attname=%s AND a.attnum > 0 AND a.attrelid = c.oid", do_quote_literal(table_orig), do_quote_literal(table_orig_pkey));
#ifdef TABLE_LOG_DEBUG_QUERY
  elog(NOTICE, "query: %s", query);
#endif /* TABLE_LOG_DEBUG_QUERY */
  ret = SPI_exec(query, 0);
  if (ret != SPI_OK_SELECT) {
    elog(ERROR, "could not check relation: %s", table_orig);
  }
  if (SPI_processed == 0) {
    elog(ERROR, "could not check relation: %s", table_orig);
  }
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "original table: OK (%i columns)", table_orig_columns);
#endif /* TABLE_LOG_DEBUG */

  /* check log table */
  snprintf(query, 249, "SELECT a.attname FROM pg_class c, pg_attribute a WHERE c.relname = %s AND a.attnum > 0 AND a.attrelid = c.oid ORDER BY a.attnum", do_quote_literal(table_log));
#ifdef TABLE_LOG_DEBUG_QUERY
  elog(NOTICE, "query: %s", query);
#endif /* TABLE_LOG_DEBUG_QUERY */
  ret = SPI_exec(query, 0);
  if (ret != SPI_OK_SELECT) {
    elog(ERROR, "could not check relation [1]: %s", table_log);
  }
  if (SPI_processed > 0) {
    table_log_columns = SPI_processed;
  } else {
    elog(ERROR, "could not check relation [2]: %s", table_log);
  }
  /* check pkey in log table */
  snprintf(query, 249, "SELECT a.attname FROM pg_class c, pg_attribute a WHERE c.relname=%s AND c.relkind='r' AND a.attname=%s AND a.attnum > 0 AND a.attrelid = c.oid", do_quote_literal(table_log), do_quote_literal(table_log_pkey));
#ifdef TABLE_LOG_DEBUG_QUERY
  elog(NOTICE, "query: %s", query);
#endif /* TABLE_LOG_DEBUG_QUERY */
  ret = SPI_exec(query, 0);
  if (ret != SPI_OK_SELECT) {
    elog(ERROR, "could not check relation [3]: %s", table_log);
  }
  if (SPI_processed == 0) {
    elog(ERROR, "could not check relation [4]: %s", table_log);
  }
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "log table: OK (%i columns)", table_log_columns);
#endif /* TABLE_LOG_DEBUG */

  /* check restore table */
  snprintf(query, 249, "SELECT pg_attribute.attname AS a FROM pg_class, pg_attribute WHERE pg_class.relname=%s AND pg_attribute.attnum > 0 AND pg_attribute.attrelid=pg_class.oid", do_quote_literal(table_restore));
#ifdef TABLE_LOG_DEBUG_QUERY
  elog(NOTICE, "query: %s", query);
#endif /* TABLE_LOG_DEBUG_QUERY */
  ret = SPI_exec(query, 0);
  if (ret != SPI_OK_SELECT) {
    elog(ERROR, "could not check relation: %s", table_restore);
  }
  if (SPI_processed > 0) {
    elog(ERROR, "restore table already exists: %s", table_restore);
  }
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "restore table: OK (doesnt exists)");
#endif /* TABLE_LOG_DEBUG */

  /* now get all columns from original table */
  snprintf(query, 249, "SELECT a.attname, format_type(a.atttypid, a.atttypmod), a.attnum FROM pg_class c, pg_attribute a WHERE c.relname = %s AND a.attnum > 0 AND a.attrelid = c.oid ORDER BY a.attnum", do_quote_literal(table_orig));
#ifdef TABLE_LOG_DEBUG_QUERY
  elog(NOTICE, "query: %s", query);
#endif /* TABLE_LOG_DEBUG_QUERY */
  ret = SPI_exec(query, 0);
  if (ret != SPI_OK_SELECT) {
    elog(ERROR, "could not get columns from relation: %s", table_orig);
  }
  if (SPI_processed == 0) {
    elog(ERROR, "could not check relation: %s", table_orig);
  }
  results = SPI_processed;
  /* store number columns for later */
  number_columns = SPI_processed;
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "number columns: %i", results);
#endif /* TABLE_LOG_DEBUG */
  for (i = 0; i < results; i++) {
    /* the column name */
    tmp = SPI_getvalue(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1);
    col_query_size += strlen(do_quote_ident(tmp)) + 2;
    /* now check, if this is the pkey */
    if (strcmp((const char *)tmp, (const char *)table_orig_pkey) == 0) {
      /* remember the (real) number */
      col_pkey = i + 1;
    }
  }
  /* check if we have found the pkey */
  if (col_pkey == 0) {
    elog(ERROR, "cannot find pkey (%s) in table %s", table_orig_pkey, table_orig);
  }
  /* allocate memory for string */
  col_query_size += 10;
  col_query_start = (char *) palloc((col_query_size + 1) * sizeof(char));
  col_query = col_query_start;
  for (i = 0; i < results; i++) {
    if (i > 0) {
      sprintf(col_query, ", ");
      col_query = col_query_start + strlen(col_query_start);
    }
    sprintf(col_query, "%s", do_quote_ident(SPI_getvalue(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1)));
    col_query = col_query_start + strlen(col_query_start);
  }
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "string for columns: %s", col_query_start);
#endif /* TABLE_LOG_DEBUG */

  /* create restore table */
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "create restore table: %s", table_restore);
#endif /* TABLE_LOG_DEBUG */

  snprintf(query, 249, "SELECT * INTO ");
  /* per default create a temporary table */
  if (not_temporarly == 0) {
    strcat(query, "TEMPORARY ");
  }
  strcat(query, "TABLE ");
  strncat(query, table_restore, 249);
  /* from which table? */
  strncat(query, " FROM ", 249);
  strncat(query, table_orig, 249);
  if (need_search_pkey == 1) {
    /* only extract a specific key */
    strncat(query, " WHERE ", 249);
    strncat(query, do_quote_ident(table_orig_pkey), 249);
    strncat(query, "=", 249);
    strncat(query, do_quote_literal(search_pkey), 249);
  }
  if (method == 0) {
    /* restore from begin (blank table) */
    strncat(query, " LIMIT 0", 249);
  }
#ifdef TABLE_LOG_DEBUG_QUERY
  elog(NOTICE, "query: %s", query);
#endif /* TABLE_LOG_DEBUG_QUERY */
  ret = SPI_exec(query, 0);
  if (ret != SPI_OK_SELINTO) {
    elog(ERROR, "could not check relation: %s", table_restore);
  }
  if (method == 1) {
#ifdef TABLE_LOG_DEBUG
    elog(NOTICE, "%i rows copied", SPI_processed);
#endif /* TABLE_LOG_DEBUG */
  }

  /* get timestamp as string */
  timestamp_string = DatumGetCString(DirectFunctionCall1(timestamptz_out, timestamp));

#ifdef TABLE_LOG_DEBUG
  if (method == 0) {
    elog(NOTICE, "need logs from start to timestamp: %s", timestamp_string);
  } else {
    elog(NOTICE, "need logs from end to timestamp: %s", timestamp_string);
  }
#endif /* TABLE_LOG_DEBUG */

  /* now build query for getting logs */
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "build query for getting logs");
#endif /* TABLE_LOG_DEBUG */

  d_query_size += d_query_size + strlen(col_query_start);
  if (need_search_pkey == 1) {
    /* add size of pkey and size of value */
    d_query_size += strlen(do_quote_ident(table_orig_pkey)) * 2 + strlen(do_quote_literal(search_pkey)) + 3;
  }

  /* allocate memory for string */
  d_query_size += 10;
  d_query_start = (char *) palloc((d_query_size + 1) * sizeof(char));
  d_query = d_query_start;

  snprintf(d_query, d_query_size, "SELECT %s, trigger_mode, trigger_tuple, trigger_changed FROM %s WHERE ", col_query_start, do_quote_ident(table_log));
  d_query = d_query_start + strlen(d_query_start);
  if (method == 0) {
    /* from start to timestamp */
    snprintf(d_query, d_query_size, "trigger_changed <= %s ", do_quote_literal(timestamp_string));
  } else {
    /* from now() backwards to timestamp */
    snprintf(d_query, d_query_size, "trigger_changed >= %s ", do_quote_literal(timestamp_string));
  }
  d_query = d_query_start + strlen(d_query_start);
  if (need_search_pkey == 1) {
    snprintf(d_query, d_query_size, "AND %s = %s ", do_quote_ident(table_orig_pkey), do_quote_literal(search_pkey));
    d_query = d_query_start + strlen(d_query_start);
  }
  if (method == 0) {
    snprintf(d_query, d_query_size, "ORDER BY %s ASC", do_quote_ident(table_log_pkey));
  } else {
    snprintf(d_query, d_query_size, "ORDER BY %s DESC", do_quote_ident(table_log_pkey));
  }
  d_query = d_query_start + strlen(d_query_start);
#ifdef TABLE_LOG_DEBUG_QUERY
  elog(NOTICE, "query: %s", d_query_start);
#endif /* TABLE_LOG_DEBUG_QUERY */
  ret = SPI_exec(d_query_start, 0);
  if (ret != SPI_OK_SELECT) {
    elog(ERROR, "could not get log data from table: %s", table_log);
  }
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "number log entries to restore: %i", SPI_processed);
#endif /* TABLE_LOG_DEBUG */
  results = SPI_processed;
  /* save results */
  spi_tuptable = SPI_tuptable;

  /* go through all results */
  for (i = 0; i < results; i++) {
    /* get tuple data */
    trigger_mode = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, number_columns + 1);
    trigger_tuple = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, number_columns + 2);
    trigger_changed = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, number_columns + 3);
    /* check for update tuples we doesnt need */
    if (strcmp((const char *)trigger_mode, (const char *)"UPDATE") == 0) {
      if (method == 0 && strcmp((const char *)trigger_tuple, (const char *)"old") == 0) {
        /* we need the old value of the pkey for the update */
        old_pkey_string = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, col_pkey);
#ifdef TABLE_LOG_DEBUG
        elog(NOTICE, "tuple old pkey: %s", old_pkey_string);
#endif /* TABLE_LOG_DEBUG */
        /* then skip this tuple */
        continue;
      }
      if (method == 1 && strcmp((const char *)trigger_tuple, (const char *)"new") == 0) {
        /* we need the old value of the pkey for the update */
        old_pkey_string = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, col_pkey);
#ifdef TABLE_LOG_DEBUG
        elog(NOTICE, "tuple: old pkey: %s", old_pkey_string);
#endif /* TABLE_LOG_DEBUG */
        /* then skip this tuple */
        continue;
      }
    }

    if (method == 0) {
      /* roll forward */
#ifdef TABLE_LOG_DEBUG
      elog(NOTICE, "tuple: %s  %s  %s", trigger_mode, trigger_tuple, trigger_changed);
#endif /* TABLE_LOG_DEBUG */
      if (strcmp((const char *)trigger_mode, (const char *)"INSERT") == 0) {
        __table_log_restore_table_insert(spi_tuptable, table_restore, table_orig_pkey, col_query_start, col_pkey, number_columns, i);
      } else if (strcmp((const char *)trigger_mode, (const char *)"UPDATE") == 0) {
        __table_log_restore_table_update(spi_tuptable, table_restore, table_orig_pkey, col_query_start, col_pkey, number_columns, i, old_pkey_string);
      } else if (strcmp((const char *)trigger_mode, (const char *)"DELETE") == 0) {
        __table_log_restore_table_delete(spi_tuptable, table_restore, table_orig_pkey, col_query_start, col_pkey, number_columns, i);
      } else {
        elog(ERROR, "unknown trigger_mode: %s", trigger_mode);
      }
    } else {
      /* roll back */
      char rb_mode[10]; /* reverse the method */
      if (strcmp((const char *)trigger_mode, (const char *)"INSERT") == 0) {
        sprintf(rb_mode, "DELETE");
      } else if (strcmp((const char *)trigger_mode, (const char *)"UPDATE") == 0) {
        sprintf(rb_mode, "UPDATE");
      } else if (strcmp((const char *)trigger_mode, (const char *)"DELETE") == 0) {
        sprintf(rb_mode, "INSERT");
      } else {
        elog(ERROR, "unknown trigger_mode: %s", trigger_mode);
      }
#ifdef TABLE_LOG_DEBUG
      elog(NOTICE, "tuple: %s  %s  %s", rb_mode, trigger_tuple, trigger_changed);
#endif /* TABLE_LOG_DEBUG */
      if (strcmp((const char *)trigger_mode, (const char *)"INSERT") == 0) {
        __table_log_restore_table_delete(spi_tuptable, table_restore, table_orig_pkey, col_query_start, col_pkey, number_columns, i);
      } else if (strcmp((const char *)trigger_mode, (const char *)"UPDATE") == 0) {
        __table_log_restore_table_update(spi_tuptable, table_restore, table_orig_pkey, col_query_start, col_pkey, number_columns, i, old_pkey_string);
      } else if (strcmp((const char *)trigger_mode, (const char *)"DELETE") == 0) {
        __table_log_restore_table_insert(spi_tuptable, table_restore, table_orig_pkey, col_query_start, col_pkey, number_columns, i);
      }
    }
  }

#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "table_log_restore_table() done, results in: %s", table_restore);
#endif /* TABLE_LOG_DEBUG */

  /* convert string to VarChar for result */
  return_name = DatumGetVarCharP(DirectFunctionCall2(varcharin, CStringGetDatum(table_restore), Int32GetDatum(strlen(table_restore) + VARHDRSZ)));

  /* close SPI connection */
  SPI_finish();
  /* and return the name of the restore table */
  PG_RETURN_VARCHAR_P(return_name);
}
示例#15
0
Datum verify_row_visible_current_setting(PG_FUNCTION_ARGS) {
    const VarChar *vis_base64 = PG_GETARG_VARCHAR_P(0);

    const char *token_base64 =
        GetConfigOption(EZBAKE_TOKEN_SETTING, false, false);

    if (!token_base64) {
        ereport(ERROR,
                (errmsg("Could not read serialized security token from session "
                        "config with key " EZBAKE_TOKEN_SETTING)));

        PG_RETURN_BOOL(false);
    }

    char *error = NULL;
    token_handle_t *token =
        ezbake_deserialize_token_base64(token_base64, &error);

    if (error) {
        ereport(ERROR,
                (errmsg("Error deserializing the security token: %s", error)));

        free(error);
        PG_RETURN_BOOL(false);
    }

    authorizations_handle_t *auths =
        ezbake_get_authorizations_from_token(token, &error);

    if (error) {
        ereport(ERROR,
                (errmsg("Error extracting auths from security token: %s",
                        error)));

        ezbake_token_handle_free(token);
        free(error);
        PG_RETURN_BOOL(false);
    }

    visibility_handle_t *vis = deserialize_vis(vis_base64);
    if (!vis) {
        ereport(ERROR,
                (errmsg("There was an error deserializing the visibility!")));

        ezbake_token_handle_free(token);
        ezbake_authorizations_handle_free(auths);
        PG_RETURN_BOOL(false);
    }

    uint32_t permissions = ezbake_get_user_permissions(auths, vis, &error);
    if (error) {
        ereport(ERROR, (errmsg("Error evaluating permissions: %s", error)));
        ezbake_token_handle_free(token);
        ezbake_authorizations_handle_free(auths);
        ezbake_visibility_handle_free(vis);
        free(error);
        PG_RETURN_BOOL(false);
    }

    ezbake_token_handle_free(token);
    ezbake_authorizations_handle_free(auths);
    ezbake_visibility_handle_free(vis);

    bool is_authorized =
        (permissions & EZBAKE_USER_PERM_READ) &&
        (permissions & EZBAKE_USER_PERM_WRITE) &&
        (permissions & EZBAKE_USER_PERM_MANAGE_VISIBILITY);

    PG_RETURN_BOOL(is_authorized);
}
示例#16
0
Datum *tidyurl(PG_FUNCTION_ARGS)
{
	VarChar *arg;
	VarChar *ret;
	int ret_size;

	char *str;
	char *res;

	char *src, *dst;
	int in, out;
	translation *t;
	int size;

	arg = PG_GETARG_VARCHAR_P(0);

	// Extract string
	size = VARSIZE(arg) - VARHDRSZ;
	str = (char *) palloc(size + 1);
	if (str == NULL)
	{
		ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
			errmsg("out of memory")));
        	PG_RETURN_NULL();
	}

	memcpy(str, VARDATA(arg), size);
	str[size] = 0;

	// Allocate result string
	res = (char *) palloc(size + 1);
	if (res == NULL)
	{
		ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
			errmsg("out of memory")));
        	PG_RETURN_NULL();
	}

	memset(res, 0, size + 1);
	
	for (in = out = 0, src = str, dst = res; *src;
		src = str + in, dst = res + out)
	{
		// FIXME: Bubble search. fix for performance
		for (t = (translation *) translator; t->tr_from; ++t)
		{
			if (strncmp(src, t->tr_from, strlen(t->tr_from)) == 0)
			{
				src = t->tr_to;
				break;
			}
		}

		// Skip unknown/untranslated utf-8 chars and non printables
		if (*src <= 32 || *src >= 127)
		{
			++in;
			continue;
		}

		// Skip double white spaces: _
		if (out && *(dst - 1) == SPACE_CHAR && *src == SPACE_CHAR)
		{
			++in;
			continue;
		}

		if (t->tr_from)
		{
			in += strlen(t->tr_from);
			out += strlen(t->tr_to);
		}
		else
		{
			++in;
			++out;
		}

		// Make sure theres enough room in result
		if (out >= size)
		{
			res = repalloc(res, size * 2 + 1);
			if (res == NULL)
			{
				ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
					errmsg("out of memory")));
				PG_RETURN_NULL();
			}

			memset(res + size, 0, size + 1);

			// Make sure dst points right
			dst = res + strlen(res);
			size *= 2;
		}

		if (t->tr_from)
		{
			strcpy(dst, src);
		}
		else
		{
			*dst = *src;
		}
	}

	// Remove trailing underscores (spaces)
	for (;*dst == SPACE_CHAR; --dst)
	{
		*dst = 0;
	}

	// Lowercase
	/*
	for (dst = res; *dst; ++dst)
	{
		if (isupper(*dst))
		{
			*dst = tolower(*dst);
		}
	}
	*/
	
	// Return result
	ret_size = out + VARHDRSZ;
	ret = (VarChar *) palloc(ret_size);
	if (ret == NULL)
	{
		ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
			errmsg("out of memory")));
		PG_RETURN_NULL();
	}

	SET_VARSIZE(ret, ret_size);
	memcpy(VARDATA(ret), res, out);

	pfree(str);
	pfree(res);

	PG_RETURN_VARCHAR_P(ret);
}